home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / sys / cbm / 4074 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  191.9 KB

  1. Path: conch.aa.msen.com!brain
  2. From: brain@conch.aa.msen.com (Jim Brain)
  3. Newsgroups: comp.sys.cbm
  4. Subject: Commodore Hacking E-Zine Issue #12 for March 1996
  5. Date: 15 Mar 1996 23:03:09 GMT
  6. Organization: Msen, Inc. -- Ann Arbor, MI.
  7. Message-ID: <4icsvd$alk@pravda.aa.msen.com>
  8. NNTP-Posting-Host: conch.aa.msen.com
  9. X-Newsreader: TIN [version 1.2 PL2]
  10.  
  11. From the cold state of Michigan, its:
  12.  
  13. @(#)top:
  14.   
  15.                    ########
  16.              ##################
  17.          ######            ######
  18.       #####
  19.     #####  ####  ####      ##       #####   ####  ####  ####  ####  ####   #####
  20.   #####    ##    ##      ####     ##   ##   ##  ###     ##    ####  ##   ##   ##
  21.  #####    ########     ##  ##    ##        #####       ##    ## ## ##   ##
  22. #####    ##    ##    ########   ##   ##   ##  ###     ##    ##  ####   ##   ##
  23. #####  ####  ####  ####  ####   #####   ####  ####  ####  ####  ####   ######
  24. #####                                                                     ##
  25.  ######            ######            Issue #12
  26.    ##################               Version 1.0
  27.        ########                      March 1996
  28.                           
  29. -------------------------------------------------------------------------
  30.  
  31. @(#)contents: Table of Contents
  32.   
  33.  
  34. Features
  35.    6. "Polygonamy": A Study in 3 Dimensions by Stephen Judd
  36.       (Reference: polygon)
  37.         Did you ever feel real time 3 Dimensional graphics was just asking
  38.         too much from a Commodore 64?  Well, ask no more, as Stephen shows
  39.         us just hoiw it can be done.  The 64 steps up to the challenge of
  40.         displaying correctly rendered shaded 3D polygons right before your
  41.         very eyes.
  42.    9. Underneath the Hood of the SuperCPU by Jim Brain
  43.       (Reference: cmdcpu)
  44.         Delve into the technical details of this new accelerator
  45.         under development by CMD.  Jim will explain its advantages 
  46.         over existing offering, epxlain the features it provides, and
  47.         dispel some myths about the unit.
  48.  
  49. Columns
  50.    4. Hi Tech Trickery by Doug Cotton
  51.       (Reference: trick)  
  52.         Trying to switch from 128 mode to 64 mode on a C128 without
  53.         human intervwention is triccky.  Doing it on modified KERNAL ROMs
  54.         is doubly so.  Doug details a routine that will work regardless of
  55.         the ROM in use.  
  56.   12. Hacking Graphics by Harsfalvi Levente
  57.       (Reference: gfx)
  58.         All you Commodore Plus/4 lovers, listen up.  Harsfalve delves into
  59.         the Commodore Plus/4 TED chip, explains its many functions and
  60.         details its various registers.  Do you know all the things the TED
  61.         chip does in addition to handle video.  Now you'll know.
  62.    
  63. Departments
  64.    1. The (cough,cough) Hacking Editor
  65.       (Reference: editor)
  66.    2. Input/Output
  67.       (Reference: io)
  68.    3. Newsfront
  69.       (Reference: news)
  70.    5. Hacking the Mags
  71.       (Reference: mags)
  72.    7. UseNuggets
  73.       (Reference: usenet)
  74.    8. FIDO's Nuggets
  75.       (Reference: fido)
  76.   10. Hack Surfing
  77.       (Reference: surf)
  78.   11. Commodore Trivia
  79.       (Reference: trivia)
  80.   13. ? DS, DS$: rem The Error Channel
  81.       (Reference: error)
  82.   14. The Next Hack
  83.       (Reference: next)
  84.   15. Hacking the Code
  85.       (Reference: code)
  86.  
  87. -------------------------------------------------------------------------
  88.  
  89. @(#)legal: Commodore Hacking Legal Notice
  90.  
  91. Commodore and the respective Commodore product names are trademarks or 
  92. registered trademarks of ESCOM GmbH.  Commodore hacking is in no way 
  93. affiliated with ESCOM GmbH, owners of said trademarks.  Commodore Hacking is 
  94. published 4 times yearly by:
  95.  
  96. Brain Innovations Inc. 
  97. 602 N. Lemen 
  98. Fenton MI  48430
  99.  
  100. The magazine is published on on-line networks free of charge, and a nominal 
  101. fee is charged for alternate mediums of transmission.  
  102.  
  103. Permission is granted to re-distribute this "net-magazine" or "e-zine" in its 
  104. entirety for non-profit use.  A charge of no more than US$5.00 may be 
  105. charged by redistribution parties to cover printed duplication and no more
  106. than US$10.00 for other types of duplication to cover duplication and media
  107. costs for this publication.  If this publications is included in a for-profit 
  108. compilation, this publication must be alternately available separately or as
  109. part of a non-profit compilation.
  110.  
  111. This publication, in regards to its specific ordering and compilations of
  112. various elements, is copyright(c) 1995 by Brain Innovations, Incorporated,
  113. unless otherwise noted.  Each work in this publication retains any and all 
  114. copyrights pertaining to the individual work's contents.  For  
  115. redistribution rights to individual works, please contact the author of said 
  116. work or Brain Innovations, Inc.
  117.  
  118. Brain Innovations, Inc. assumes no responsibility for errors or omissions in 
  119. editorial, article, or program listing content.  
  120.  
  121. -------------------------------------------------------------------------
  122.  
  123. @(#)info: Commodore Hacking Information
  124.   
  125. Commodore Hacking is published via the Internet 4 times yearly, and is 
  126. presented in both ISO-8859-1 and HTML versions.  This and previous issues can 
  127. be found at the Commodore Hacking Home Page 
  128. (http://www.msen.com/~brain/chacking/), as well as via FTP 
  129. (ftp://ccnga.uwaterloo.ca/pub/cbm/hacking.mag/)
  130.  
  131. In addition, the Commodore Hacking mail server can be used to retrieve each 
  132. issue.  To request a copy of an issue, please send the following electronic 
  133. mail message:
  134.  
  135. To: brain@mail.msen.com
  136. Subject: MAILSERV
  137. Body of Message:
  138.  
  139. help
  140. catalog
  141. send c=hacking12.txt 
  142. quit
  143.  
  144. To retrieve a PKZIP 1.01 archive of the individual articles in Commodore
  145. Hacking, request the file c=hacking12.zip
  146.  
  147. To subscribe to the Commodore Hacking and receive new issues as 
  148. they are published, add the following command to you MAILSERV message 
  149. prior to the quit command:
  150.  
  151. subscribe c=hacking Firstname Lastname msglen
  152.  
  153. (msglen is largest size of email message in line you can receive.  Each
  154. line is roughly 50 characters, so 600 lines is about 30000 bytes.  When
  155. in doubt, choose 600)
  156.  
  157. example:
  158.  
  159. subscribe c=hacking Jim Brain 600
  160.  
  161. Although no fee is charged for this magazine, donations are gladly accepted 
  162. from corporate and individual concerns.  All monies will be used to defray 
  163. any administrative costs, subscribe to publications for review, and 
  164. compensate the individual authors contributing to this issue.
  165.  
  166. Any persons wishing to author articles for inclusion in Commodore Hacking are 
  167. encouraged to view the submission guidelines on the WWW
  168. (http://www.msen.com/~brain/pub/c-hacking-submit.txt) or via the MAILSERV 
  169. server (send c-hacking-submit.txt).  
  170.  
  171. =========================================================================
  172.  
  173. @(#)rch: Reading C=Hacking
  174.   
  175. Starting with Issue 11 of Commodore Hacking, the new QuickFind indexing 
  176. system is utilized to aid readers of the text version in navigating the
  177. magazine.  At the top  of each article or other important place in the
  178. magazine, a word prefixed with a special string is present.  (See the
  179. title of this article for an example.  Throughout the magazine, if an
  180. article is mentioned, it will be followed by a reference string.  For
  181. example, if we mentioned this article, we would add (Reference: rch) after
  182. the name.  By using your favorite editor's search function and searching
  183. for the string after the word "Reference:", prefixed by the magic prefix
  184. string, will move you directly to the article of choice.  To merely skip to
  185. the next article in the magazine, search only for the magic prefix string.
  186.  
  187. Some handy indexing strings possibly not referenced anywhere are:
  188.  
  189. top      top of issue
  190. bottom   bottom of issue
  191. contents table of contents
  192. legal    legal notice
  193.  
  194. For those with access to a UNIX system, the command "what" can be
  195. run on the issue, which will result in all the article titles being
  196. printed.
  197.  
  198. A slightly different magic prefix string "@(A)" is used to delimit
  199. sub-topics or main heading in articles.  The text after the magic string
  200. differs depending on article content.  For the Input/Output column
  201. (Reference: io), the text after the magic prefix will either be "c" for 
  202. comment, or "r" for response.  In features and columns, a number after
  203. the prefix indicates the ordinal of that heading or sub-topic in the
  204. article.  If a specific sub-topic is referenced elsewhere in the article,
  205. a sub-topic reference will be indicated.  A reference to "@(A)r" would
  206. be written as "(SubRef: r)".
  207.  
  208. As time goes on, the role of this indexing system will be expanded and
  209. changed to ease navigation of the text version, but minimize the clutter
  210. added by these extra items.
  211.  
  212. =========================================================================
  213.  
  214. @(#)editor: The Hacking Editor
  215.             by Jim Brain (brain@mail.msen.com)
  216.  
  217. Speed and the Web.  The owners are asking about it.  The developers are
  218. looking into it.  The market is readying itself for it.  No, not the PC
  219. market, I'm referring to the Commodore 8-bit market.  The same market 
  220. usually referred to as "mature".  The same market usually referred to with
  221. a condescending tone.  Well, mature we might be, but isn't that considered
  222. a good thing? People are supposed to mature as they grow older.  As such,
  223. they are revered and looked up to.  What parallels can we draw here?
  224.  
  225. If you haven't anything about the planned introduction of the CMD SuperCPU
  226. 20 MHz accelerator cartridges for the C64 and C128, shame on you!  You
  227. need to stay in touch more.  For those who have, let's not overdo the
  228. hype.  CMD isn't the first to produce such a cartridge, but they will be
  229. the first to introduce 20 MHz as a speed option.  C128 users will rejoice
  230. as the first 128 mode accelerator ships from CMD.  When this happens, 
  231. performance approaching that of the venerable Intel 80386 will be as 
  232. close as the on/off switch.  
  233.  
  234. The explosion of interest in the Internet and the World Wide Web is
  235. changing the way people view computers.  Until recently, it seemed that
  236. people thought only computer systems including a 32 or 64 bit CPU,
  237. multiple megabytes of RAM, gigabyte hard drives, infinite resolution 
  238. monitors and million bit sound cards were worth owning.  Commodore
  239. owners have felt the sting of ridicule as they continually take blow
  240. after blow for remaining loyal to a machine with much to offer.  Well,
  241. be patient, because 1996 might be the year of the "network computer", a
  242. smaller comuter system that trades all the fancy features of bloated PCs
  243. for a smaller size, cost, and a connection to the Internet.  Big names
  244. like IBM, Oracle and Apple are pushing this idea, which would bring to
  245. market systems with modest RAM, small drives, television displays, and
  246. small operating systems.  Does this idea sound familiar?  It should, as
  247. it describes many features of Commodore 8-bit systems.  No, the CBM
  248. 8-bit still lacks a few items present in the IBM/Apple/Oracle designs,
  249. but the bulk of features are already available on your so called 
  250. "obsolete" CBM machine.  Don't gloat yet, as there's much to do, but
  251. if your friends tout the benefits of such a machine, gently remind them
  252. that you own of of the first and best, a Commodore 8-bit.
  253.  
  254. Enjoy YOUR magazine,
  255.  
  256. Jim Brain (brain@mail.msen.com)
  257. editor
  258.  
  259. ============================================================================
  260.  
  261. @(#)io: Input/Ouput
  262.  
  263. Obviously, Commodore Hacking depends on the comments and article submissions
  264. from the Commodore community to flourish.  Everyone sees the articles, but
  265. let's not forget those comments.  They are very helpful, and every attempt
  266. is made to address concerns in them.  Address any comments, concerns, or
  267. suggestions to:
  268.  
  269. Commodore Hacking
  270. 602 N. Lemen
  271. Fenton, MI  48430
  272. brain@mail.msen.com (Internet)
  273.  
  274. @(A)c: Time Travellin'
  275.  
  276. From: Robin Harbron <rfharbro@flash.lakeheadu.ca>
  277.  
  278. Dear C=Hacking,
  279. I was looking at the Commodore Hacking page (fantastic magazine) and 
  280. noticed that the "Publishing Schedule for 95-96" has 1995 for all the 
  281. dates, while I assume that the last 4,5,or 6 probably should be 1996.  
  282. Thanks for everything!
  283.  
  284. Robin
  285.  
  286. @(A)r:
  287. Yep, we must have just returned from our time travel experiments when we
  288. wrote that in the WWW pages.  Note that the magazine was correct, but the
  289. home was in error.  Oh well.  
  290.   
  291. @(A)c: Run (Down) the Software
  292.  
  293. From: sis319@educ.di.unito.it 
  294.  
  295. Dear C=Hacking,
  296. I really appreciate the work you are doing with the Commodore Hacking 
  297. on-line magazine. I like the new look and the new features you added, such 
  298. as newsfront and hacking the mags.
  299.  
  300. I would like to see on the magazine some reviews about the latest and more
  301. interesting PD and Shareware software (with a list of FTP sites where these 
  302. are available) and hardware products.
  303.  
  304. Please note that Commodore Hacking is the only Commodore magazine I can 
  305. easily find here in Italy, because all the Italian magazine there were are
  306. dead and all the foreign magazines that were distributed, such as "RUN", 
  307. "Compute!'s Gazette", "64'er" are either dead or no longer distributed.
  308.  
  309. @(A)r:
  310. We appreciate your comments about the new look of C=Hacking.  As for the
  311. inclusion of reviews, we're looking into it.  it's not that we don't want
  312. to do it, just that we need to schedule the reviews (Commodore Hacking
  313. shouldn't do all of them, as that creates bias), and determining what
  314. software is worthy of review.  Look for some reviews in upcoming issues.
  315.  
  316. @(A)c: Separate But Equal
  317.        
  318. From: alan.jones@qcs.org (Alan Jones)
  319.  
  320. Dear C=Hacking,
  321. I like your new version of C=Hacking.  I like the idea of including 
  322. relevant news and summaries of other magazines and disks.  Size should not 
  323. be a constraint, although you should publish early when it exceeds some 
  324. critical size.  Don't scrimp on source code listings and uuencoded files!  
  325. There is no other publication for this sort of bulky technical stuff.  
  326. It would also be wonderfull if we could get an apropriate means for 
  327. including diagrams or pictures, viewable by C64/128 users.  I would REALLY 
  328. like to have the C64/128 html viewer/printer that you mentioned.  You may 
  329. not know it but we came very close to having Al Angers Tower article 
  330. submitted to C-hacking in place off Commodore World, but C-Hacking could 
  331. not really handle drawings and photos.  
  332.  
  333. I have been separating C=Hacking into separate articles and files, archiving 
  334. them and placing the archive(s) on a local BBS.  This compacts the length 
  335. and makes it easier to read and use.  I try to make C=Hacking easy to 
  336. download and use locally, but I still want to keep it as whole and original 
  337. as possible.  
  338.  
  339. @(A)r:
  340. Alan, we're glad you approve of the new format.  We're going to try to keep
  341. the size so that it will always fit onto 2 1541 disk sides.  C=Hacking
  342. is still working on the HTML viewer, but it's taking a back seat to other
  343. more pressing issues.  We'll have it finished at some point, and start 
  344. distributing the magazine that way as well.   As for your separation, we
  345. appreciate the work you've done to make C=hacking easier to distribute.  
  346. With issue #12, we are offering an archive of all the article in separate
  347. files.  The archival method has not been chosen just yet, but look on the
  348. C=Hacking MAILSERV server for the file.  
  349.  
  350. Late news: check the Commodore Hacking Information (Reference: info) for 
  351. more information of retrieving an archive of the individual articles.
  352.  
  353. @(A)c: Enquiring Minds Wanna Know!
  354.        
  355. From: Peter Hofman <HOFMAN%NLEV00@btmv56.se.bel.alcatel.be>
  356.  
  357. Dear C=Hacking
  358. I would like to make a suggestion for your "Commodore Hacking E-Zine" page. 
  359. Maybe you could add a link to a page with some info about the next issue of 
  360. Commodore Hacking, so people know what will be in the next issue. The reason
  361. why I make this suggestion is that I read the other issues, and I am very
  362. curious, what will be published.
  363.  
  364. @(A)r:
  365. Good suggestion.  So good, in fact, that we implemented it.  Mind you, we
  366. can't completely predict the future, so the information in the link may
  367. not exactly reflect the contents of the issue when it is published, but
  368. we'll try to keep the two in sync.
  369.  
  370. @(A)c: Pulling It Out of the Closet
  371.        
  372. From: bloodbane@rlion.com (Jeffrey S Cotterman)
  373.  
  374. Dear C=Hacking,
  375. Well, I was just writing to say I think you did a great job on C=
  376. Hacking... I am throughly amazed by the support and the interest in
  377. the Commodores.  I have a Vic-20, C-64, C-128, and an Amiga 1000.
  378. I have not used any of them in a long time, I have two Beamers that I
  379. use more. However seeing all this stuff makes me want to turn them back
  380. on.  (Actually I use the 64 quite a bit for playing games, plus the
  381. 1702 monitor works great with a Super Nintendo!)  I used to be quite
  382. proficient at the 64, but it is slipping.  I will try to get my butt
  383. back in gear so maybe I can post an article or two.... Geesh, and just
  384. last year I got rid of all my Run and Compute's Gazette magazines....
  385. Oh well I will look through the cobwebs and see what I can come up
  386. with.   Anyway, congrats on the mag, I think it's going great.
  387.  
  388. @(Ar:
  389. We appreciate the thanks.  And, if we can get one person to pull a C64
  390. or other CBM machines out of the closet and turn it back on through what we
  391. do, it is worth it.
  392.  
  393. @(A)c: C=Hacking Flunked Geography
  394.        
  395. From: Peter Karlsson <dat95pkn@idt.mdh.se>
  396.  
  397. Dear C=Hacking,
  398. I saw your mention of Atta Bitar in Commodore Hacking.
  399.  
  400. German? Heheheh... :-)
  401.  
  402. Anyway, the English information page is available now, but not much will=20
  403. be in English (sorry). It is a Swedish paper :)
  404.  
  405. From: Erik Paulsson <ep@algonet.se>
  406.  
  407. Dear C=Hacking,
  408. I'm the editor of the Swedish mag Atta Bitar (8 bitter), so I thought I 
  409. should drop you a line.       
  410.  
  411. I really like the "new" C= Hacking it's really great, keep up the good work!
  412.  
  413. One small comment regarding Atta Bitar, it's not in German, it's in swedish.
  414. I just thought you should know...       
  415.  
  416. @(A)r:
  417. Picky, picky, picky.  It's not like we would react that way if you said
  418. Commodore Hacking came from CANADA.  Wait, hold it.... I guess we would.
  419. Correction made.  Thanks for the update, and if we ever learn Swedish, we'll
  420. try to read it again.  (Anyone want to translate for us?)
  421.  
  422. =========================================================================
  423.  
  424. @(#)news: Newsfront
  425.  
  426. *  Matthew Desmond, the author of Desterm, has recently resurfaced and
  427.    states that he is once again working on something.  Although Commodore
  428.    Hacking discourages hourds from emailing him to ask about Desterm
  429.    progress, Matt's email address is mdesmond@ionline.net, for those
  430.    who wish to register Desterm or express their support.  
  431.  
  432. *  Speaking of email addresses, LOADSTAR will be changing theirs.  As
  433.    the online service GEnie has recently been purchased and new fares
  434.    have been put in place, LOADSTAR finds its monthly bill rising too 
  435.    high for pleasure.  As of March, 1996, the Internet address for
  436.    LOADSTAR will be loadstar@softdisk.com.
  437.  
  438. *  While we're on the subject of email addresses, CMD has expanded their
  439.    set of Internet email address contacts in order to better support its
  440.    online users.  The following addresses are now valid:
  441.    
  442.    Email Address             Usage
  443.    
  444.    cmd.sales@the-spa.com     Questions relating to product prices, 
  445.                              catalog requests, ordering onformation,
  446.  
  447.    cmd.support@the-spa.com   Technical questions concerning CMD products.
  448.  
  449.    cmd.cw@the-spa.com        Questions or comments relating to Commodore
  450.                              World magazine.
  451.  
  452.    doug.cotton@the-spa.com   superceded the cmd-doug@genie.geis.com address
  453.                              previously used for all CMD inquires.  Should
  454.                              be used items not applicable to the above 
  455.                              addresses
  456.                              
  457.    cmd.cac@the-spa.com       Direct link to Charles A. Christianson, VP of
  458.                              Sales and Marketing.  Again, shuld be used for
  459.                              items not applicable to above email addresses.
  460.  
  461. *  We're not done yet, as COMMODORE CEE has recently moved its office and
  462.    is now at:
  463.    
  464.    
  465.       COMMODORE CEE
  466.       5443 College Oak Drive #26
  467.       Sacramento, CA 95841
  468.       Jack Vanderwhite@cee-64.wmeonlin.sacbbx.com (Contact)
  469.       ceejack@crl.com (Contact)
  470.       Jack Vanderwhite, editor.
  471.       Fidonet: 1:203/999
  472.       (916) 339-3403 (Bulletin Board System)
  473.  
  474. *  The Commodore Zone.  No, it's not an alternate universe, but a magazine
  475.    for the Commodore gamer and/or demo fan.  Each issue's 40 pages is full
  476.    of reviews, interviews with top programmers, and an exclusive comic
  477.    strip done by Alf Yngve.  Accompanying each issue is a 5.25" disk or
  478.    tape containing game demos, demos, and full games.  Free software is
  479.    often included.
  480.    
  481.    More information can be obtained through:
  482.    
  483.       Commodore Zone
  484.       34 Portland Road
  485.       Droitwich
  486.       Worcestershire
  487.       WR9 7QW
  488.       England
  489.                  
  490.    Copies are available for UK3.00.  Make checks payable to Binary
  491.    Zone PD.
  492.       
  493. *  Also in the magazine front, Computer Workshops, Inc. is planning a
  494.    World Wide Web magazine to feature gaming.  The blurb follows:
  495.    
  496.       CWI is working on a new Web magazine to feature the newest and
  497.       hottest in c64/128 Gaming. But, before we can do that, we need 
  498.       your help. Send us what you're working on, or, if you're a 
  499.       programmer with something for review, send us that too! Also,
  500.       if you've got a product you'd like to advertise, we'd like to
  501.       hear that too (a la Yahoo).
  502.  
  503.       Send it to either, or both:
  504.  
  505.          spectre@deepthought.armory.com
  506.  
  507.          Computer Workshops/Cameron Kaiser
  508.          ATTN: Commodore Gamer
  509.          3612 Birdie Drive
  510.          La Mesa, CA 91941-8044
  511.  
  512.       (Please don't send binaries to the spectre@ address.)
  513.       
  514.       Thanks for your support, and barring any unforseen difficulties,
  515.       Commodore Gamer should be ready to premiere in about two months.
  516.  
  517.       Cameron Kaiser
  518.  
  519. *  The December 10, 1995 edition of the Waco Tribune Herald put one of our
  520.    own in the spotlight.  The headline read "'Antique' PCs have loyal 
  521.    fans here, elsewhere." and was written by Sherry W. Evans,  
  522.    Tribune-Herald staff writer.  The Commodore user taking the spotlight 
  523.    was Karen Allison, known on the FIDO network.  Sharing the spotlight
  524.    with Karen was Brad Jackson, of Commodore Country, who said that
  525.    a C64 was raced against an Intel 386 using identical programs, and 
  526.    the 64 won.  Allison claims in the article that "the challenge is finding
  527.    creative ways to solve problems since Commies have had no ... support..."
  528.    Allison indirectly mentioned GeoFAX, the GEOS Fax program, and a low
  529.    cost Tax program she uses to pay the IRS every year.  Allison, a diehard
  530.    "Commie", explained in the article that "(People who use IBMs) all
  531.    think my Commodore can't do much and is just a toy.  But for a toy,
  532.    this computer does pretty good."
  533.  
  534. *  For those good with an assembler and the VIC/SID registers, Driven 
  535.    Magazine is sponsoring a 4K Demo competition.  The deadline is July
  536.    1st 1996.  Although the program must run on an NTSC 64, PAL programmers
  537.    are encouraged to enter.  The entries will be released as a group at the
  538.    close of the contest, and entrants can re-use their entries.  The
  539.    complete rules follow:
  540.    
  541.                       4k Demo Contest Rules
  542.  
  543.    - 1 file only (no secondary loading)
  544.    - max file size is $1000 bytes
  545.    - must be started with BASIC 'run'
  546.    - 1 demo per coder; multiple entries per group are allowed.
  547.      Multiple coders can collaborate on a single demo, so long
  548.      as there remains only 1 demo per coder.
  549.    - credits for all parts of an entry must be given at time of entry;
  550.      if a particular credit is unknown, mark it as "unknown"
  551.    - demos will be evaluated on NTSC c64.
  552.    
  553.    Anything not specifically denied above is allowed; e.g. packing + 
  554.    crunching, use or non-use of music or graphics, entries by PAL 
  555.    sceners, etc.
  556.              
  557.    Deadline = July 1.
  558.    
  559.    Entries need to go to coolhand:
  560.    
  561.       coolhand@kaiwan.com
  562.    
  563.    or postal mail to:
  564.    
  565.       Bill Lueck
  566.       17411 Mayor Lane
  567.       Huntington Beach, California, 92647
  568.       USA
  569.    
  570.    Evaluators will be selected shortly, but will include Coolhand and 2-3
  571.    other non-demomaking NTSC demo enthusiasts.
  572.    
  573.    There will be categories for evaluation, but there will not be separate
  574.    winners - the scores from the categories will be added together.  The
  575.    categories will be announced after the evaluation team is established,
  576.    but they will include design, originality, technical difficulty,
  577.    artistic impact, and best overall impact, etc (all tentative at this
  578.    time).
  579.    
  580. *  Bo Zimmerman has put his Commodore 128 on the net.  No, he didn't
  581.    log into some Internet service from his 128, he actually PUT it on
  582.    the 'Net.  Running the BBS program called "Zelch", the machine can be
  583.    accessed by telntting to 147.26.162.107 and giving "zelch" as the
  584.    login.  Bo warns that the system is running off a single 1571 at 2400
  585.    bps, so don't hog the system, OK.  
  586.    
  587.    For the technical types, the 128 is connected to the serial port
  588.    of a Linux PC hooked up the Internet.  Nonetheless, we're getting 
  589.    closer to the standalone CBM Internet server.
  590.  
  591. *  In the March 1996 issue of _Next Generation_ magazine, on pages 31 
  592.    and 32, NG published a very unflattering definition of the Commodore
  593.    64 as part of their: "The Next Generation 1996 Lexicon A to Z:
  594.    A definitive guide to gaming terminology".  Among other things, the
  595.    definition's writer confused the Apple II with the Commodore 64 and
  596.    stated that the C64 could not display lowercase, a common problem
  597.    on early Apples.  The writer was biased in favor of the Apple II line,
  598.    but evidently had never used a C64 or never owned an early Apple II.
  599.    In either case, the fervor caused by the definition sparked an outrage
  600.    in the USENET newsgroup comp.sys.cbm.  See UseNuggets (Reference: usenet)
  601.    for the scoop.
  602.    
  603.    If you would like to write to _Next Generation_, even though the
  604.    article claimed no comments would be heard on the subject, or to
  605.    request a copy of the article, their address is:
  606.    
  607.    Editorial:
  608.    
  609.       Email:   ngonline@imagine-inc.com
  610.       Fax:     (415) 696-1678
  611.       Phone:   (415) 696-1688
  612.       
  613.    Subscriptions:
  614.    
  615.       Email:   ngsubs@aol.com
  616.       Phone:   (415) 696-1661
  617.  
  618.    Post Office Mail:
  619.    
  620.       Next Generation
  621.       Imagine Publishing, Inc.
  622.       1350 Old Bayshore Highway, Suite 210
  623.       Burlingame, CA 94010
  624.  
  625. =========================================================================
  626.  
  627. @(#): trick: RUN64: Moving to 64 Mode
  628.              by Doug Cotton (doug.cotton@the-spa.com)
  629.              
  630. Reprinted with permission. Copyright (c) 1996 Creative Micro Designs, Inc.
  631.  
  632. Various routines have been used over the years to allow programs to move
  633. from 128 mode to 64 mode without user intervention. With the advent of
  634. modified Kernal ROMs (JiffyDOS, RAMLink, and others) many of the methods
  635. that work on stock machines have either failed to do the job completely,
  636. and in some cases fail all together.
  637.  
  638. RUN64 is the answer to those users looking to worm their way into
  639. 64 mode without having to be concerned with the different Kernal ROMs. The
  640. program is presented here in two ways: as a BASIC program that will move to
  641. 64 mode and load the program you request, and as assembly language source
  642. for ML programmers.
  643.  
  644. BASIC Notes: The BASIC version uses the ML code produced by the
  645. assembly language source. This is found in the data statements beginning at
  646. line 660. When you run it, the program will ask for the file name, device
  647. number, and file load type (BASIC or ML). The first two parameters should
  648. be self-explanatory, but the load type may confuse you. If the file you're
  649. loading is itself a small loader (1, 2 or 3 blocks) then it will almost
  650. always be an ML program. Likewise, if you usually load the file with a
  651. ",8,1" at the end of the load statement, it's ML. If you're loading a
  652. larger file, or a file that you normally load with just a ",8", then use
  653. the BASIC option.
  654.  
  655. Also, if you remove the REM instructions from lines 150 through 180
  656. the program becomes a dedicated loader. Just specify the file name and
  657. other options within those lines.
  658.  
  659. @(A): How The Routine Works
  660.  
  661. RUN64 performs its trick by masquerading as a cartridge.  When started,
  662. the code copies the payload routines into $8000, with the special header 
  663. that signifies a cartridge is present.  It then resets the system.  The
  664. system initializes and checks for a cartridge.  When it finds the payload
  665. routines, it executes them just like it would any cartridge.  The
  666. pseudo-cartridge routines then switch out BASIC, call the remainder of
  667. the KERNAL init routines, switch BASIC in, call some BASIC init routines,
  668. set the "load" and "run" lines on screen, dump some "returns" into the
  669. keyboard buffer, and finally jump into the BASIC interpreter.
  670.  
  671. @(A): Assembly Language Notes: 
  672.  
  673. The source code is pretty well documented, and ML programmers should have 
  674. little trouble figuring out what everything does. Take note of the Buddy 
  675. Assembler .off pseudo-op used a few lines below the code label. This 
  676. adjusts all fixed references within the code that follows it to execute 
  677. properly at $8000.
  678.  
  679. The code uses some indirect vectors (ibv, ibr and ibm) to overcome not
  680. having an indirect jsr opcode, and switches out BASIC ROM temporarily since
  681. the KERNAL finishes intializing by indirectly jumping through the address
  682. at $a000.  Since the target application hasn't been loaded yet, the code
  683. must put its own address at $a000 to regain control.
  684.  
  685. To use the routine, just set up a file name at filename, put a
  686. device number in $ba, set the load type in sa1flag, then execute the
  687. routine.
  688.  
  689.  
  690.    100 rem run64.bas (c) 1996 creative micro designs, inc.
  691.    110 :
  692.    120 print "{CLEAR/HOME}run64"
  693.    130 print
  694.    140 :
  695.    150 rem f$="filename" : rem filename
  696.    160 rem dv=peek(186)  : rem device number (8, 9, 10, etc.)
  697.    170 rem l$="a"        : rem load type (a=basic, b=ml [,1])
  698.    180 rem goto 310
  699.    190 :
  700.    200 input "filename";f$
  701.    210 input "{2 SPACES}device";dv$ : if dv$="" then 230
  702.    220 poke 186,val(dv$)
  703.    230 dv = peek(186)
  704.    240 print
  705.    250 print "select a or b"
  706.    260 print "{2 SPACES}a.
  707.    load";chr$(34);f$;chr$(34);",";right$(str$(dv),len(str$(dv))-1)
  708.    270 print "{2 SPACES}b.
  709.    load";chr$(34);f$;chr$(34);",";right$(str$(dv),len(str$(dv))-1);",1"
  710.    280 get l$ : if l$<>"a" and l$<>"b" then goto 280
  711.    290 print
  712.    300 print l$;" selected"
  713.    310 print
  714.    320 print "going to 64 mode!"
  715.    330 :
  716.    340 : rem poke in main ml
  717.    350 :
  718.    360 i = 6144
  719.    370 read d
  720.    380 if d = -1 then 450
  721.    390 poke i,d
  722.    400 i = i + 1
  723.    410 goto 370
  724.    420 :
  725.    430 : rem poke in filename
  726.    440 :
  727.    450 for i = 0 to len(f$)-1
  728.    460 : poke 6356+i, asc(mid$(f$,i+1,1))
  729.    470 next i
  730.    480 poke 6356+i,0
  731.    490 :
  732.    500 : rem poke in device number
  733.    510 :
  734.    520 if dv$="" then 570
  735.    530 poke 186,val(dv$)
  736.    540 :
  737.    550 : rem check load type
  738.    560 :
  739.    570 poke 6324,0
  740.    580 if l$="b" then poke 6324,1
  741.    590 :
  742.    600 : rem sys to ml
  743.    610 :
  744.    620 sys6144
  745.    630 :
  746.    640 : rem ml data
  747.    650 :
  748.    660 data 32,115,239,160,0,185,22,24
  749.    670 data 153,0,128,200,208,247,165,186
  750.    680 data 141,157,128,76,77,255,9,128
  751.    690 data 9,128,195,194,205,56,48,169
  752.    700 data 0,141,4,128,120,169,0,141
  753.    710 data 22,208,32,132,255,32,135,255
  754.    720 data 169,230,133,1,169,43,141,0
  755.    730 data 160,169,128,141,1,160,76,248
  756.    740 data 252,169,231,133,1,32,148,128
  757.    750 data 32,151,128,32,154,128,162,0
  758.    760 data 189,159,128,240,6,32,210,255
  759.    770 data 232,208,245,162,0,189,190,128
  760.    780 data 240,6,32,210,255,232,208,245
  761.    790 data 162,0,189,180,128,240,6,32
  762.    800 data 210,255,232,208,245,173,158,128
  763.    810 data 240,10,169,44,32,210,255,169
  764.    820 data 49,32,210,255,169,145,32,210
  765.    830 data 255,32,210,255,173,157,128,133
  766.    840 data 186,162,0,189,185,128,240,6
  767.    850 data 157,119,2,232,208,245,173,158
  768.    860 data 128,208,2,169,4,133,198,76
  769.    870 data 157,227,108,149,227,108,152,227
  770.    880 data 108,155,227,0,0,17,17,68
  771.    890 data 86,61,80,69,69,75,40,49
  772.    900 data 56,54,41,58,76,79,65,68
  773.    910 data 34,0,34,44,68,86,0,13
  774.    920 data 82,213,13,0,70,73,76,69
  775.    930 data 78,65,77,69,0,-1
  776.  
  777.  
  778.  
  779. ; RUN64.SRC
  780. ; Doug Cotton & Mark Fellows
  781. ; (c) 1996 Creative Micro Designs, Inc.
  782. ;
  783.         .org    $1800
  784.         .obj    run64.obj
  785.  
  786. run64   jsr     $ef73   ; go slow
  787. ;
  788.         ldy     #0      ; copy cartridge
  789. -       lda     code,y  ; code to $8000
  790.         sta     $8000,y
  791.         iny
  792.         bne     -
  793. ;
  794.         lda     $ba     ; get device number
  795.         sta     dvtemp  ; and store it
  796. ;
  797.         jmp     $ff4d   ; go 64
  798. ;
  799. code    .byt    $09,$80 ; cold start
  800.         .byt    $09,$80 ; warm start
  801.         .byt    $c3,$c2,$cd,$38,$30     ; cbm80
  802. ;
  803.         .off    $8009   ; offset code
  804. ;
  805.         lda     #$00    ; disable
  806.         sta     $8004   ; cartridge code
  807.         sei             ; disable interrupts
  808. ;
  809.         lda     #$00    ; zero out
  810.         sta     $d016   ; VIC control Register
  811. ;
  812.         jsr     $ff84   ; initialize I/O
  813.         jsr     $ff87   ; initialize RAM
  814.         lda     #$e6    ; switch in RAM
  815.         sta     $01     ; at $A000
  816.         lda     #<reenter       ; set up return vector
  817.         sta     $a000   ; at $A000 to bypass
  818.         lda     #>reenter       ; BASIC statup during
  819.         sta     $a001   ; initialization
  820. ;
  821.         jmp     $fcf8   ; let Kernal finish up
  822. ;
  823. reenter lda     #$e7    ; back from Kernal, set
  824.         sta     $01     ; $A000 back to ROM
  825. ;
  826.         jsr     ibv     ; initialize vectors
  827.         jsr     ibr     ; initialize RAM
  828.         jsr     ibm     ; initialize memory
  829. ;
  830.         ldx     #$00    ; output screen text
  831. -       lda     part1,x ; to form LOAD statement
  832.         beq     +
  833.         jsr     $ffd2
  834.         inx
  835.         bne     -
  836. ;
  837. +       ldx     #$00    ; print filename to be
  838. -       lda     filename,x      ; loaded at end of
  839.         beq     +       ; LOAD statement
  840.         jsr     $ffd2
  841.         inx
  842.         bne     -
  843.  
  844. ;
  845. +       ldx     #$00    ; print device
  846. -       lda     part2,x ; variable at end
  847.         beq     +       ; of LOAD statement
  848.         jsr     $ffd2
  849.         inx
  850.         bne     -
  851. ;
  852. +       lda     sa1flag ; check secondary
  853.         beq     +       ; address flag for load
  854.         lda     #','    ; type, and print a
  855.         jsr     $ffd2   ; comma and a 1 at end
  856.         lda     #'1'    ; of LOAD statement if
  857.         jsr     $ffd2   ; load type is ML
  858. ;
  859. +       lda     #$91    ; print two CRSR up
  860.         jsr     $ffd2
  861.         jsr     $ffd2
  862. ;
  863.         lda     dvtemp  ; get device number
  864.         sta     $ba     ; and store
  865. ;
  866. +       ldx     #$00    ; put [RETURN]rU[RETURN]
  867. -       lda     keydata,x       ; into keyboard buffer
  868.         beq     +
  869.         sta     $0277,x
  870.         inx
  871.         bne     -
  872. ;
  873. +       lda     sa1flag ; get load type and
  874.         bne     +       ; branch if it is ML (1)
  875.         lda     #$04    ; if not ML, change .A
  876. +       sta     $c6     ; store kybd buffer NDX
  877. ;
  878.         jmp     $e39d   ; enter BASIC
  879. ;
  880. ibv     jmp     ($e395) ; initialize vectors
  881. ibr     jmp     ($e398) ; initialize RAM
  882. ibm     jmp     ($e39b) ; initialize memory
  883. ;
  884. dvtemp  .byt    $00     ; device number temp
  885. sa1flag .byt    $00     ; load type (1=ML,
  886.                         ; 0=BASIC)
  887. ;
  888. part1   .byt    $11,$11 ; 2 CRSR up
  889.         .byt    'dv=peek(186):load'
  890.         .byt    $22     ; quote
  891.         .byt $00
  892. ;
  893. part2   .byt    $22     ; quote
  894.         .byt    ',dv'
  895.         .byt $00
  896. ;
  897. keydata .byt    $0d     ; [RETURN]
  898.         .byt    'rU'    ; shortcut for RUN
  899.         .byt    $0d     ; [RETURN]
  900.         .byt    $00
  901. ;
  902. filename        .byt    'filename'      ; name of file to load
  903.         .byt $00        ; 00 byte must follow filename!
  904. ;
  905.         .end
  906.  
  907. =========================================================================
  908.  
  909. @(#)mags: Hacking the Mags
  910.  
  911. Not everything good and/or technical comes from Commodore Hacking, which
  912. is as it should be.  (I still think we have the most, though...)  Thus,
  913. let's spotlight some good and/or technical reading from the other
  914. Commodore publications.
  915.  
  916. If you know of a magazine that you would like to see summarized here, let 
  917. C=Hacking know about it.  These summaries are only limited by Commodore 
  918. Hacking's inability to purchase subscriptions to all the Commodore 
  919. publications available.  We are very grateful to those publications that
  920. send complimentary copies of their publications for review.
  921.     
  922. @(A): COMMODORE CEE
  923.    At press time, Issue #5 was in the works, so we'll detail the contents
  924.    next time. However, see Newsfront (Reference: news) for address changes
  925.    for COMMODORE CEE.       
  926.  
  927. @(A): Commodore 128/64 Power User Newsletter (CPU)
  928.    A while back, Gosser Games, Ltd., Inc. sent us a sample issue of this
  929.    publication, which is published exclusively with a Commodore 128
  930.    machine, much like the defunct dieHard.  For those just getting into
  931.    the BBS arena, the "Cyberspace Cowboy", R.J. Smulkowski, previously
  932.    writing this article in dieHard, has moved his column to CPU.  The 
  933.    content is light, but useful, and a godsend for new users.  Reviews
  934.    of GeoFAX and "Radio Controlled Flight Simulator" also grace the
  935.    pages.  Printed on regular bond at 7" by 9", the 16 page publication
  936.    is small but full of potential.  
  937.  
  938. @(A): Commodore World
  939.    If you remember last time we spoke of Commodore World, we asked the
  940.    rhetorical question: What's up with those funky graphics?  We didn't
  941.    expect an answer, but editor Doug Cotton called to explain the curious
  942.    eye-catchers.  He also mentioned that asst. editor Jenifer Esile was
  943.    having trouble creating them now that we made fun of them.  We're sorry
  944.    Jenifer.  We want you to continue, since they save us the cost of 
  945.    commercial inkblot cards for our self-psycho-analysis sessions here
  946.    at Hacking Headquarters. (just joshing, we can be so mean sometimes).
  947.    Speaking of Jenifer, we're not sure when she started, but the last few 
  948.    issues seem more colorful.  Sure, content is great, but packaging is
  949.    everything.  We've even caught PC-centric folks perusing our copy.
  950.    Kudos to CMD for that effect.
  951.   
  952.    Obviously, Commodore World iisn't for all, but the content is
  953.    consistent.  Issues 11 and 12 are no exception.  In issue 11, Doug 
  954.    tackles high level serial bus routines and includes ML source, 
  955.    Gaelyne Moranec shares some useful WWW pages, and Jim Butterfield 
  956.    explains the nasty NULL character and its implications.  Of special
  957.    interest in this issue is the two page spread on changing device
  958.    numbers on the pesky 1541 drives.  The article is worthy of archival
  959.    for reference. CMD also takes time to note that the SuperCPU cartridge 
  960.    will contain a 65C816 8/16 bit CPU, not the earlier mentioned 65C02
  961.    8-bit CPU.
  962.    
  963.    Issue 12 should be subtitled the "SuperCPU" issue.  We think its
  964.    great, but it's definitely not subtle.  Doug Cotton and Mark Fellows
  965.    preview the unit while Jim Brain details the CPU inside it.  CMD 
  966.    ntes that the 10 MHz version has been scrapped, but the 128 version 
  967.    has been added, dealying introduction until April for the 64 version.
  968.    C=H was hoping to review a prototype unit this issue, but we'll do it
  969.    next time.  Jason Compton and Katherine Nelson describe HTML, the
  970.    markup language for World Wide Web pages, and Jim Butterfield explains
  971.    using KERNAL devices 0 (keyboard) and 3 (screen).  For those wanting 
  972.    to run a Bulletin Board System, Max Cottrell describes how to ensure 
  973.    success. Of special interest in this issue is a photo of the prototype 
  974.    accelerator.  We won't even hint of our opinions on this round of
  975.    funky graphics....  
  976.    
  977. @(A): Driven
  978.    Driven #11 waxes somewhat philosophic about the demo scene in 1995.  The
  979.    tone expresses a tinge of disappoinment with the hope that 1996 will
  980.    be a better year for demos.  This issue also ushers in Driven's first
  981.    crack at covering the PAL scene.  As part of the 1995 year-end review,
  982.    a complete list of releases is given.  In the news section, Charles
  983.    Christianson's blurb on the CMD SuperCPU is reprinted, and King Fisher
  984.    of Triad discusses the origins of the demo scene in "Cyberpunk".
  985.    
  986.    If you've ever wondered what goes on inside the mind of a demo "scene"
  987.    programmer, Driven #12 will fill you in.  Interviews with Phantom of
  988.    the group FOE and Zyron of F4CG are included, both telling it as it is.
  989.    For those wanting to set up or design a BBS system Mitron takes a look
  990.    at CNET DS2  and details some general guidelines on how the networking
  991.    code works.  Of special note is a review of this issue's Polygonamy
  992.    sample code (Reference: polygon).  
  993.  
  994. @(A): LOADSTAR
  995.    Issue 139 starts off with the announcement that LOADSTAR is taking over
  996.    the dieHard Spinner disk subscriptions, as reported in C=H#11.  File
  997.    Base 64 from John Serafino will be useful for anyone organizing their
  998.    disk collection.  Fender Tucker claims it is better than DCMR, the
  999.    supposed standard.  Jeff Jones cooks up the "Ultimate INPUT" for people
  1000.    wanting the perfect BASIC INPUT routine.  The claims are substantial and
  1001.    Jeff delivers.  The included LOADSTAR LETTER #29 contains another
  1002.    article in the Internet series.
  1003.  
  1004.    As we started Issue 140, we noticed something was different.  We
  1005.    couldn't place it at first, but then Jeff alerted us to the change.
  1006.    LOADSTAR now has highlighted words in the text, and the color scheme
  1007.    can be changed and saved.  Nice for the eyes.  In addition, LS#140 can
  1008.    mark up text using highlights, bold, and underline on printers that
  1009.    support such features.  Bob Markland presents a ML module that
  1010.    provides better random numbers, and Fender Tucker challenges
  1011.    programmers ML programmers to write a routine that searches an in
  1012.    memory dictionary for a word.  Speed is the key.  C=H gets some space,
  1013.    as Issue 11 is reprinted in the 3.5" version.  Of particular note to
  1014.    programmers is Don Forsythe's "Hidden Clocks" article that describes
  1015.    in detail the CIA TOD clocks and their bugs, err "features".                  
  1016.  
  1017.    It's funny, but the LOADSTAR LETTER #40 that comes with LS #140 is 
  1018.    subtitled "Special Commodore Hacking Issue".  We were expecting C=H
  1019.    articles, but that shows just how egotistical we can be.  Jeff Jones
  1020.    filled the issue with rumors of new products, handy tips, and
  1021.    information about CMD's SuperCPU.  Of particular interest is the
  1022.    information about Craig Bruce modifying his Swiftlink to do 115,200 bps.
  1023.  
  1024.    Right before we went to press, issue 141 showed up in the mailbox.  #141
  1025.    starts off with the changes of operation since LOADSTAR publication
  1026.    was taken over by J & F Publishing.  The first is their new address:
  1027.  
  1028.    LOADSTAR
  1029.    606 Common Street
  1030.    Shreveport, LA  71101
  1031.    
  1032.    Also, they say checks should now be made out to LOADSTAR, not Softdisk.
  1033.    
  1034.    For all you TUI (Text User Interface) folks, Jeff Jones goes over how
  1035.    to create "buttons" that depress on screen when activated.  Source code
  1036.    is provided as well, which is rare for LOADSTAR.  Of particular interest
  1037.    to us was Terry Flynn's "Virtual Optics" slideshow.  Hard to describe,
  1038.    it displays impossible constructions and 3D illusions.  Even C=H gets
  1039.    some space, as issues 3 and 4 are available on the 3.5" disk version.
  1040.    Jim Brain supplies article 4 in the Internet series on LOADSTAR LETTER
  1041.    #31, included with the issue.  Of special note is LOADSTAR's new 
  1042.    Internet address, given in the LL as loadstar@softdisk.com.  See 
  1043.    Newsfront (Reference: news) for more information.
  1044.  
  1045. @(A): LOADSTAR 128
  1046.    We loaded up LS128 #30 for a look-see.  Dave's Term, the 128 
  1047.    Telecommunications Program presented in the last 4 issues, seems to be
  1048.    one focus of this issue.  Don Graham supplies a keyboard overlay and
  1049.    macros for the terminal program, while David Jensen includes a spell
  1050.    checker.  In the issue as well is ZED, the 128 editor of editors from
  1051.    Craig Bruce.
  1052.    
  1053. @(A): Vision
  1054.    At press time, Issue #8 was in the works, so we'll detail the contents
  1055.    next time.
  1056.  
  1057. Other magazines not covered in this rundown include:
  1058.  
  1059. *  _The Underground_ 
  1060. *  _Gatekeeper_
  1061. *  _Commodore Network_
  1062. *  _64'er_
  1063. *  _Atta Bitar_ (_8 bitter_)
  1064. *  _Commodore Zone_
  1065. *  _Commodore Gazette_
  1066.  
  1067. In addition, others exist that C=Hacking is simply not aware of.  As soon
  1068. as we can snag a copy of any of these, or get the foreign language ones 
  1069. in English :-), we will give you the scoop on them.  
  1070.  
  1071. ============================================================================
  1072.  
  1073. @(#): Polygonamy: A Study in 3 Dimensions
  1074.       by Stephen L. Judd (sjudd@nwu.edu)
  1075.  
  1076. We've been making some pretty small potatoes for a while now, so
  1077. the time has come for a little more ambition and challenge.  I decided to
  1078. think up a real challenge, containing problems that I had no idea how to
  1079. solve, and see what I could come up with.
  1080.  
  1081. I set out to create a 3D virtual world for the C64, e.g. a space
  1082. populated with various three-dimensional objects, which I could wander around
  1083. in.  I wanted it to be full-screen 320x200 hires bitmapped.  Furthermore, I
  1084. wanted the objects to be solid, and since there are only two colors I
  1085. wanted to be able to put patterns on the faces.  I also wanted it to
  1086. translate nicely to the 128's VDC chip, in 2MHz mode.  Finally, naturally, I
  1087. wanted the program to be fast.  This was the framework in which I placed
  1088. myself, and a few other ideas presented themselves along the way.  The
  1089. outcome of all of this is Polygonamy.
  1090.  
  1091. Just a brief history of this project: I have wanted to do a 3D
  1092. world for a very long time, and have been thinking about it for some
  1093. time in the back of my head; my imagination was probably first fired
  1094. the first time I played Elite.  I wrote down the necessary equations one
  1095. afternoon last summer, for a high school student I was teaching, and
  1096. the equations are very simple.  I took a break to get some work of
  1097. measureable value accomplished, but in October I began work on the graphics
  1098. algorithm.  I worked steadily on this for two months, and in December I
  1099. finally began to code the graphics.  In mid-January, I got them to work.
  1100. Adding the rest took a few weekends more.  I have about 128 pages of notes,
  1101. analytical calculations, and BASIC test programs in my C64 notebook (which
  1102. is, I think, a nice number of pages to have :).  My original plans were
  1103. to place five objects in the world, but time and memory constraints whittled
  1104. that down to three.  One of my disks self-destructed about the day I was
  1105. ready to finish, so I had to reconstruct a bunch of tables, but other than
  1106. that I finally managed to finish it up, albeit with a few rough edges ;).
  1107.  
  1108. Although the concepts from previous articles are used as a solid
  1109. foundation, the code is almost 100% from scratch -- I only borrowed a
  1110. tiny piece of code from an earlier program, and even that I modified
  1111. somewhat.
  1112.  
  1113. One caveat before we begin: I am primarily interested in the
  1114. challenge of designing the algorithms, which means I like to come up
  1115. with my own solutions.  Thus, you may find more efficient methods
  1116. in a graphics book or perhaps in someone else's code; I have examined
  1117. neither, so I have no idea what the relative merit of my algorithms
  1118. may be.  These are simply my solutions to challenges placed before me.
  1119. And if you know of a better way to do things, please feel free to email
  1120. me!
  1121.  
  1122. Furthermore, I consider the code a test of the theory.  Some of my
  1123. assumptions work and some do not, and these will be considered at the end
  1124. of this article.
  1125.  
  1126. Finally, I am not including the source code.  For one thing, it is big.  
  1127. Like, _HUGE_, man.  I had to split it up when I ran out of editor memory
  1128. on my 128 (which, incidentally, forced me to figure out Merlin 128's very
  1129. cool and very powerful linker feature).  I will include numerous code 
  1130. fragments in assembly and BASIC which demonstrate all the important 
  1131. concepts.
  1132.  
  1133. By the way, if you are interested in measuring frame rates, you can
  1134. use the first object.  Every full 360 degree revolution is 128 frames. 
  1135. So time how long it takes to complete a full rev (or maybe several), and 
  1136. divide that number into 128, to get an idea of frames per second.
  1137. For a rundown of frame rates for stock and SuperCPU operation, see
  1138. "Underneath the Hood of the SuperCPU" (Reference: cmdcpu) found
  1139. elsewhere in thi issue.
  1140.  
  1141. Some brief acknowledgements: This project would not have happened without
  1142. the extremely powerful macro and linking capabilities of the Merlin 128
  1143. assembler, by Glen Bredon.  It would have been _really_ tough without
  1144. JiffyDOS and my FD-2000, from CMD.  I used my Action Replay extensively
  1145. for debugging, and without the excellent documentation for the 64, such as
  1146. the PRG and Mapping the 64, this would have been a nightmare.  Finally, I 
  1147. must acknowledge my friend George Taylor; a few days before I was all 
  1148. finished I explained some routines to him, and he made a great suggestion 
  1149. which made my fast fill routine blaze.
  1150.  
  1151. Okay, WAY too much talk.  There are a ton of issues involved with this 
  1152. project so let's just wade in hip-deep and deal with them as they come.
  1153.  
  1154. @(A): The Equations
  1155.       -------------
  1156.  
  1157. First some relaxing abstraction.  In previous articles we have discussed
  1158. how to project an object in three dimensions through the origin into a 
  1159. plane.  We have also discussed rotations in three dimensions.  In 
  1160. principle, then, we have all the mathematics we need to do a 3D world.
  1161.  
  1162. But we should be thoughtful.  Let's say we're standing in the world and 
  1163. turn to the right; we can either rotate ourselves, and change the 
  1164. direction we are looking, or we can rotate the world around us, so that 
  1165. we are always looking 'forward'.  This may bother you on physical grounds,
  1166. but the two are mathematically equivalent.  Given the way we have derived
  1167. our projection routines, it should be clear that we want to rotate the 
  1168. objects in the world around us.
  1169.  
  1170. (Or, to put it another way, we are at the center of the world, and the 
  1171. world revolves around us.)
  1172.  
  1173. We have another issue: how do we know when an object is visible or not?
  1174. How do we know when we've bumped into an object (or blown it out of the
  1175. sky :)?  Moreover, if we have ten objects, and each object has six points,
  1176. it would be a real drag to have to rotate all sixty points, especially
  1177. if none of the objects were even visible.      
  1178.  
  1179. It should be clear that we really want to define every object relative
  1180. to some center of the object.  So we keep track of the center of each 
  1181. object, and rotate and translate the centers, and only calculate the 
  1182. full object if it is visible.  We of course want to define the object 
  1183. relative to this center.
  1184.  
  1185. What happens to this center when we translate or rotate the world?
  1186.  
  1187. Let's simplify our model a little bit and only deal with rotations about 
  1188. one axis, e.g. we are driving a tank and can move forwards and backwards,
  1189. and turn left or right.  The generalization to other axes is very 
  1190. straightforward, but this way we can think in two dimensions instead 
  1191. of three.
  1192.  
  1193. First we need to agree on a coordinate system.  For my system I let the 
  1194. x-axis go _up_ a page of paper, the y-axis comes up out of the page, and 
  1195. the z-axis goes from left to right.  Thus, I am standing on the paper in
  1196. the x-z plane, at the origin, with the y-axis extending upwards from me. 
  1197. If you still don't understand my orientation, draw a little picture.
  1198.  
  1199. I am going to choose my orientation so that I am always looking straight
  1200. down the x-axis, e.g. in the direction that x is increasing.  Thus, if I
  1201. walk forwards or backwards, this corresponds to decreasing or increasing
  1202. the x-component of the center coordinate:
  1203.  
  1204.    let C=(cx,cy,cz)
  1205.    move forwards => cx=cx-1
  1206.    move backwards=> cx=cx+1
  1207.  
  1208. So far so good.  As always, draw a picture if you can't visualize it.  
  1209. That takes care of translations, what about rotations?
  1210.  
  1211. We certainly know how to rotate points about the origin.  In particular,
  1212. if we have a point with coordinates (x1,z1) and rotate it clockwise by 
  1213. an angle s, we get the new point as follows:   
  1214.  
  1215.    (x1,z1) -> (x1*cos(s)+z1*sin(s), z1*cos(s)-x1*sin(s))
  1216.  
  1217. So that's easy enough.  The problem is that we have this big object
  1218. sitting around this point, and need to figure out what to do with it!
  1219.  
  1220. Consider the following: let's say we have a line out some distance from 
  1221. the origin,
  1222.  
  1223.                          X
  1224.                          X
  1225.             |            X
  1226.  z-axis ----O------------c----     c=center
  1227.             |            X
  1228.             |            X
  1229.           Origin         X <---- line
  1230.  
  1231. and we rotate it by some amount theta about the origin:
  1232.  
  1233.                       X
  1234.                       XX
  1235.                        Xc      c=rotated center
  1236.             |           XX 
  1237.  z-axis  ---O------------XX-
  1238.             |             X
  1239.                           XX
  1240.  
  1241. You can see (from my incredible ASCII artwork) that the line is now at an
  1242. angle with respect to the origin.
  1243.  
  1244. Imagine that we draw a line from the origin to the center of the point, 
  1245. in the first picture (or get a pencil and paper and actually do it), so 
  1246. that we have the letter "T" laying on its side.  Now we rotate this "T" 
  1247. by some angle theta, so that the top of the "T" -- our line -- has now
  1248. been rotated.
  1249.  
  1250. The stem of the "T" meets the top of the "T" at the center point c.  Drop
  1251. a line from the rotated center straight down to the z-axis, and call this
  1252. line l2.  Since the T is at a right angle, and we have rotated it by an
  1253. angle theta, the angle between our line and the z-axis is 90-theta.  But
  1254. this means that the angle between our line (the top of the "T") and the
  1255. line l2 is just theta.
  1256.  
  1257. Thus, if we rotate the center by an amount theta, all we have to do 
  1258. is rotate the object by an amount theta *about the center*, and our 
  1259. perspectives will all be correct.  How is that for simple?  It should
  1260. be clear now that this works no matter where the "center" of the object
  1261. is chosen.  Thus, our center is not some physical center of the object,
  1262. but rather the center of rotation of the object.
  1263.  
  1264. Since this is true of rotations about any axis, we now know how to 
  1265. generalize to higher dimensions.
  1266.  
  1267. Note further that we can now implement local rotations -- that is, let's 
  1268. say the object is a tank, and this tank turns independently of whether 
  1269. or not we turn.  Piece of cake.
  1270.  
  1271. You can also see that the rotations are cumulative.  If we turn to the 
  1272. left, and then turn left again, we can simply apply two rotations to the 
  1273. points of the object.  In fact, if we turn left, move forwards, and then
  1274. move left again, we still apply just two rotations to the points of the
  1275. object; the center, however, has moved.
  1276.  
  1277. This is quite important, as it allows us to measure an object's relative
  1278. rotation to us, whether or not it is visible.  Remember that we only 
  1279. want to rotate the points that define an object when the object is 
  1280. visible.  We never actually change the points which define an object.
  1281. Instead, we track how much the object needs to rotate, and rotate the
  1282. original points by that amount.
  1283.  
  1284. The center of the object will change with each rotation and translation.
  1285. We never change how we define an object about this center, though.  We
  1286. simply apply a rotation to the original points when appropriate.  The 
  1287. object centers must be kept track of because they can undergo translation
  1288. as well as rotation.
  1289.  
  1290. To summarize then: we define each object relative to a center of 
  1291. rotation.  The center determines where the object is located in the
  1292. world, and allows us to operate on centers when we need to rotate or
  1293. translate the world.  It also lets us perform local operations on an
  1294. object, so that we could, for instance, have a spinning cube located
  1295. inside our world.  If an object's center is visible then we can consider
  1296. the object to be visible, and plot it.
  1297.  
  1298. Whoops -- what does it mean to be 'visible'?  Well, think about yourself.
  1299. You can see things when they are in front of you.  Or, to be more 
  1300. precise, you have a field of vision.  Perhaps a decent model of this 
  1301. would be a cone.  I think a better model, certainly one which is
  1302. easier to deal with computationally, is the intersection of two planes:
  1303. a pyramid.  Anything which lies within this pyramid we consider visible,
  1304. and anything which lies outside we consider not visible.
  1305.  
  1306. Two-dimensionally, we draw a little wedge extending from the origin.  
  1307. Anything within the wedge we count as visible, and anything outside
  1308. of it we count as not visible.  The sides of this wedge are two lines, 
  1309. with equal but opposite slope (i.e. slope=+/-m).
  1310.     
  1311.  \ Visible /
  1312.   \  View /  Outside of visual area
  1313.    \Area /
  1314.     \   /
  1315.      \ /
  1316.       * <--- Me
  1317.  
  1318. Probably lines at some angle are more reasonable than others.  But I'm a
  1319. simple guy, and the two simplest lines I can draw are at 45 degree angles
  1320. from the axis, so their slope is +/-1.  Thus, any points which lie 
  1321. between the lines x+z=0 and x-z=0 are visible.  If the center of an 
  1322. object is within this area, we will consider the object visible.  That 
  1323. is, if cx+cz>0 and cx-cz>0 the object is visible.        
  1324.  
  1325. One last thing: if we are too close to the object, we either want to 
  1326. bump into it (i.e. not move) or else not display it.  So we also need to 
  1327. check if cx<x0 for some x0.
  1328.  
  1329. We are now in a position to write some simple code.  I wrote the
  1330. following in evil Microsoft QBasic, but BASIC7.0 on the 128 would work
  1331. just as well, although you need to change the variables (I didn't have my
  1332. 128 handy, otherwise I would have written this on the 128):
  1333.  
  1334. @(A): Polygon Prototype Code
  1335.  
  1336.    SCREEN 1 '320x200
  1337.  
  1338.    delta= 3    'Rotations will be in 3 degree increments
  1339.    rad= 3.1415926/180
  1340.    cdel= COS(rad*delta)
  1341.    sdel= SIN(rad*delta)
  1342.    theta=0
  1343.    d=-135
  1344.    x0= 60      'Bumped into the object?
  1345.    REM z0 y0 would be 160,100 to place the object in the center
  1346.    REM of the screen
  1347.    y0= 170  'I want the bottom of screen to be ground
  1348.    z0= 160
  1349.  
  1350.    REM Set up the object
  1351.    REM Tetrahedron: 0,sqrt(3),0  0,0,1  0,0,-1  2,0,0
  1352.    DIM obx(4), oby(4), obz(4)
  1353.  
  1354.    obx(1)= 0
  1355.    oby(1)= 50*SQR(3)
  1356.    obz(1)= 0
  1357.    obx(2)= 0
  1358.    oby(2)= 0
  1359.    obz(2)= 50
  1360.    obx(3)= 0
  1361.    oby(3)= 0
  1362.    obz(3)= -50
  1363.    obx(4)= 100
  1364.    oby(4)= 0
  1365.    obz(4)= 0
  1366.  
  1367.    cx= 100
  1368.    cy= -10
  1369.    cz= 0
  1370.  
  1371.    REM Get input
  1372.    main:
  1373.  
  1374.    DO
  1375.      a$=INKEY$
  1376.    LOOP UNTIL a$<>""
  1377.  
  1378.    IF a$="[" THEN cx=cx-20
  1379.    IF a$="/" THEN cx=cx+20
  1380.    IF a$=";" THEN GOSUB rotl
  1381.    IF a$="'" THEN GOSUB rotr
  1382.  
  1383.    IF cx<x0 THEN CLS: GOTO main:
  1384.    IF cx<cz OR cx+cz<0 THEN CLS: GOTO main:
  1385.  
  1386.    ctheta= COS(rad*theta)
  1387.    stheta= SIN(rad*theta)
  1388.  
  1389.    p1x= cx + ctheta*obx(1) + stheta*obz(1)   'Rotate and add to center
  1390.    p1y= cy + oby(1)
  1391.    p1z= cz + ctheta*obz(1) - stheta*obx(1)
  1392.    p1y= y0 + d*p1y/p1x          'Project and add offset
  1393.    p1z= z0 + d*p1z/p1x
  1394.    [... similar for p2x,p2y,p2z,...,p4x,p4y,p4z]
  1395.  
  1396.    CLS
  1397.    LINE (p1z, p1y)-(p2z, p2y)
  1398.    [... lines between p2-p3, p3-p1, p1-p4, p4-p2, p4-p3]
  1399.  
  1400.    GOTO main:    'Main loop
  1401.  
  1402.    REM rotate left
  1403.    rotl:
  1404.        theta= theta + delta
  1405.        blah= cdel*cx + sdel*cz
  1406.        cz= -sdel*cx + cdel*cz
  1407.        cx= blah
  1408.    RETURN
  1409.  
  1410.    rotr:
  1411.        theta= theta-delta
  1412.        blah= cdel*cx - sdel*cz
  1413.        cz= sdel*cx + cdel*cz
  1414.        cx= blah
  1415.    RETURN
  1416.  
  1417. (You may note that cx=cx+20 is used for a translation, instead of cx=cx+1.
  1418. This will be detailed later).
  1419.  
  1420. So much for the easy part.
  1421.  
  1422. @(A): Filling
  1423.       -------
  1424.  
  1425. If there is one thing that the previous programs have taught us, it is 
  1426. that graphics are slow.  At least, they are far and above the major thing
  1427. slowing down the program, and deserve the most attention and thought for
  1428. improvement.  Moreover, because there is lots of looping involved, the
  1429. elimination of just a few instructions can translate to thousands of 
  1430. cycles saved.
  1431.       
  1432. We have examined several fill routines up to now, but neither of them is
  1433. up to the task of Polygonamy.  The cookie-cutter method is OK, but doesn't
  1434. allow multiple objects, and certainly doesn't allow pattern fills.  Using
  1435. an EOR-buffer is just plain slow and inefficient and a big drag.  So it's
  1436. time to rethink this problem.
  1437.     
  1438. Recall that on the 64 the bitmap screen is divided into 8x8 cells, which
  1439. are arranged horizontally in rows.  It's a pretty kooky way of doing 
  1440. things, but we shall overcome.
  1441.  
  1442. First of all it should be clear that we want to fill from left to right
  1443. (as opposed from top to bottom).  We can then fill a byte at a time, 
  1444. instead of dinking in little pixels at a time.
  1445.  
  1446. Previously we used a custom character set to plot into.  One of the major
  1447. reasons for doing so was to use Y as the Y-coordinate, so that storing a
  1448. particular point was as simple as STA COLUMN,Y.  We can still use this
  1449. idea, but only within each row.  That is, if we let Y=0..7, we can address
  1450. each individual pixel-row within each 8x8 block row with an STA ADDRESS,Y.
  1451.  
  1452. For real speed, we are going to want an unrolled fill routine.  That is,
  1453. we don't want to mess around with loop counters and updating pointers and
  1454. such.  Since there are 25 rows on the screen (25 times 8 = 200 pixels
  1455. high) we are probably going to need 25 separate fill routines.      
  1456.      
  1457. I constructed my fill routine as follows:
  1458.  
  1459.             STA COL1,Y
  1460.             DEX
  1461.             BEQ :DONE
  1462.             STA COL2,Y
  1463.             DEX
  1464.             BEQ :DONE
  1465.             STA COL3,Y
  1466.             ... etc.
  1467.    :DONE    RTS
  1468.    
  1469. Thus X would be my counter into the number of columns to fill, A can
  1470. contain our pattern to fill with, and Y can range from 0..7 to index the
  1471. individual rows within the block.  The first thing to notice is that each
  1472. STA/DEX/BEQ code chunk is six bytes.  So, all we need to do is calculate
  1473. which row to start filling at, multiply by six, and add that number to
  1474. the start of the fill routine.  The idea is then to jump into the correct
  1475. place in the fill, and let it fill the right number of columns, stored in
  1476. X.
  1477.  
  1478. There is a little problem though -- what we're talking about doing is an 
  1479. indirect JSR, and there is no such thing.  But it's easy enough to fake,
  1480. because we can use an indirect JMP.  So a call to the fill routine would
  1481. look like the following:
  1482.  
  1483.          ...
  1484.          JSR FILL
  1485.          ...
  1486. FILL     JMP (ADDRESS)
  1487.  
  1488. where ADDRESS simply points to the correct entry point in the fill routine.
  1489.  
  1490. Moreover, you may also note that 40 columns times 6 bytes/column is 240
  1491. bytes, so that each little fill routine handily fits in a page.  Thus,
  1492. moving between rows in the bitmap corresponds to a simple decrement or
  1493. increment of the high byte of the ADDRESS pointer.  
  1494.  
  1495. This was the state of things when, days before I was to be all done with
  1496. Polygonamy, I mentioned it to my friend George Taylor, who suggested the
  1497. following modification: instead of using X to count how many columns to
  1498. fill, just make the fill routine:
  1499.  
  1500.          STA COL1,Y
  1501.          STA COL2,Y
  1502.          STA COL3,Y
  1503.          ...
  1504.  
  1505. Then, insert an RTS into the right place in the routine.  Thus, we 
  1506. calculate which column to stop filling at, multiply by three, and stick
  1507. an RTS in the fill routine at that point.  To fix it up we stick an
  1508. STA ..,Y back on top of the RTS.
  1509.         
  1510. I don't think you're going to make a fill routine faster than that :).
  1511.  
  1512. Moreover, note that each fill routine takes up just 120 bytes, so we can
  1513. now fit two fill routines in each page.  I did not do this, but it is
  1514. easy to do, and instantly frees up 25 pages.           
  1515.  
  1516. @(A): Filled Polygons
  1517.       ---------------
  1518.       
  1519. I mean, hey, this _is_ "Polygonamy", so let's talk polygons, and lots of
  1520. them.
  1521.  
  1522. Clearly all that is needed to draw an object are the left and right
  1523. endpoints of the object, since everything in-between will be filled.
  1524.  
  1525. An observation to make is that if you take a slice out of a convex
  1526. polygon, the slice will intersect the polygon at exactly two points.
  1527. Another, more important, observation is to note that the highest and
  1528. lowest point of a polygon will always be at a vertex.  Finally, it is
  1529. important to note that any vertex of a polygon has exactly two lines
  1530. extending out of it, one to the left, and one to the right.
  1531.  
  1532. Consider a piece of a polygon:
  1533.  
  1534.   \         /
  1535.    \       /
  1536.     \     /
  1537.      \   /
  1538.       \ /
  1539.        *  <--- Vertex v0
  1540.  
  1541. where the vertex v0 is the lowest point of the polygon.  All that needs
  1542. to be done is to move upwards (DEY), compute the left and right points
  1543. of the polygon at that point, and then fill between the two (JSR FILL).
  1544.       
  1545. The idea then is to start at the bottom (or the top) and to steadily move
  1546. upwards while _simultaneously_ calculating the endpoints of the left and
  1547. right lines, and filling in-between.  But we need the equations of the
  1548. left and right lines to do this.
  1549.     
  1550. Now it's time for another observation.  Let's say we have a polygon with
  1551. n vertices v1, v2, ..., vn, and furthermore that as we move between these
  1552. points we move around the polygon counter-clockwise.  Thus v3 is to the
  1553. right of v2, v1 is to the left of v2, v4 is to the right of v3, etc.
  1554. For example:
  1555.  
  1556.       v1____v3
  1557.         \  /
  1558.          \/
  1559.          v2
  1560.  
  1561. What happens if we rotate this polygon?
  1562.  
  1563.       v2____v1
  1564.         \  /
  1565.          \/
  1566.          v3
  1567.  
  1568. The vertices have changed position, but *their order has not*.  v3 is
  1569. still to the right of v2, and v1 is still to the left.
  1570.  
  1571. Now we have a real plan.  We simply define the polygon as a list of
  1572. points v1 v2 v3 ... vn.  We then figure out which one is lowest, i.e. has
  1573. the smallest (or greatest) y-coordinate, call this vertex vm (vmax).  The
  1574. endpoints of the left and right lines are vm-1,vm and vm,vm+1.  So move
  1575. along those lines until the next vertex is reached.  At that point,
  1576. recompute the appropriate line, and keep moving upwards until the top of
  1577. the polygon is reached.
  1578.  
  1579. Perhaps an example would be helpful:
  1580.  
  1581.         v1
  1582.         |\
  1583.         | \ v3
  1584.         | /
  1585.         |/
  1586.         v2
  1587.  
  1588. v2 is the minimum.  The left line has endpoints (v1,v2) and the right
  1589. line has endpoints (v2,v3).  We steadily move along the left and right
  1590. lines as we creep upwards.  At some point we hit v3, and at this point
  1591. we compute a new equation for the right line, this time with endpoints
  1592. (v3,v1).  Now we continue to creep upwards and move along the left and
  1593. right lines, until we hit v1, at which point we are finished.
  1594.  
  1595. It is important to keep in mind that the order of the points never
  1596. changes.  We don't need to do anything complicated like sorting the 
  1597. points; we only need to find the lowest point, and branch left and right
  1598. from there, keeping in mind that the points are cyclic (i.e. v1 is to the
  1599. right of vn).
  1600.  
  1601. It is now time to start thinking about code.  One aspect of the fill 
  1602. routine we haven't considered is the clear.  In the past the entire draw 
  1603. buffer was cleared and then the new stuff was drawn into it.  But this 
  1604. seems like a bit of a waste; it seems wasteful to clear a bunch of memory 
  1605. that is just going to be overwritten again.  So, as long as we can do it
  1606. efficiently, it might be smart to combine the clear and fill routines.
  1607.  
  1608. Here is how Polygonamy does it: If a line needs to be cleared, then it
  1609. is cleared up to the edges of the object, but the part that is going to
  1610. be filled is ignored.  (It isn't clear if this provides any substantial 
  1611. efficiency gains, though).
  1612.  
  1613. To see the status of a particular line, a table is used, containing a 
  1614. value for each Y-coordinate.  If the entry is 255 then the line is clear,
  1615. if it's 0 then the line has old junk in it, and if it's 1 then the line
  1616. has new junk in it.  Thus we only clear the line if its entry in the fill
  1617. table is a zero.
  1618.  
  1619. So a fill routine might flow like the following:
  1620.  
  1621.    let Y count from 7..0
  1622.  
  1623.    If we are at the left endpoint then recalculate the left line.
  1624.    If we are at the right endpoint the recalculate the right line.
  1625.    Update xleft & xright
  1626.    If line needs to be cleared then clear line.
  1627.    If the starting fill column is different than the previous fill
  1628.        column then update the pointers, etc.
  1629.    Plot the left and right endpoints (since the fill routine only plots
  1630.        eight bits at a time)
  1631.    Fill the in-between parts
  1632.    Update Y
  1633.    If Y passes through zero then update fill entry point, set Y=7 etc.
  1634.    Keep going until we reach the top
  1635.  
  1636. The next thing to figure out is how to calculate the left and right
  1637. lines.  We do have the old line routine, which we could use to advance
  1638. to the left and right endpoints, but clearly this isn't too efficient.
  1639.  
  1640. The question is: if the y-coordinate increases by one, then how much does
  1641. the x-coordinate increase by?  The equation of a line is:
  1642.  
  1643.    (y-y0) = m*(x-x0)  m=slope
  1644.    
  1645. or
  1646.  
  1647.    change in y = m*change in x
  1648.  
  1649. So, if the change in y is 1, then then the change in x is 1/m.  All we
  1650. need to do then is calculate the inverse-slope=dx/dy, where dx=x2-x1 and
  1651. dy=y2-y1, and add this to the x-coordinate with each step in y.
  1652.  
  1653. Isn't this a fraction?  Sure, big deal.  The fraction can be written
  1654. as dx/dy = N + Rem/dy, where N is an integer, and Rem is the remainder,
  1655. which is always less than dy.  So to calculate x=x+dx/dy:
  1656.  
  1657.    x= x+N
  1658.    xrem= xrem+Rem
  1659.    If xrem>=dy then x=x+1:xrem=xrem-dy
  1660.  
  1661. As usual, we want to start xrem at dy/2, which has the effect of rounding
  1662. numbers up.
  1663.  
  1664.    10 REM LINE ROUTINE TAKE TWO SLJ 11/24/95
  1665.    12 REM ACTUALLY IT'S A FILL RTY NOW
  1666.    15 GRAPHIC 1,1
  1667.    20 X0=160:Y0=100
  1668.    30 X1=5:Y1=-50:X2=7:Y2=11:XL=X1:YL=Y1:Y=Y1
  1669.    35 X3=50:Y3=Y1:X4=X3+100:Y4=Y2:XR=X3:YR=Y3
  1670.    40 D1=Y2-Y1+1:DX=X2-X1:LI=INT(DX/D1):LR=DX-LI*D1
  1671.    45 TL=INT(D1/2)
  1672.    46 D2=Y4-Y3+1:DX=X4-X3:RI=INT(DX/D2):RR=DX-RI*D2
  1673.    48 TR=INT(D2/2)
  1674.    50 DRAW1, X0+X1,Y0-Y1 TO X0+X2,Y0-Y2, X0+X3,Y0-Y3 TO X0+X4,Y0-Y4
  1675.    60 REM MAIN LOOP
  1676.    70 XR=XR+RI:TR=TR+RR:IF TR>=D2 THEN TR=TR-D2:XR=XR+1
  1677.    75 DRAW1, X0+XL,Y0-Y TO X0+XR,Y0-Y
  1678.    80 XL=XL+LI:TL=TL+LR:IF TL>=D1 THEN TL=TL-D1:XL=XL+1
  1679.    90 REM DRAW1, X0+XL,Y0-Y TO X0+XR,T0-T
  1680.    100 Y=Y+1:IF Y<=Y2 THEN 60
  1681.  
  1682. In this program (x1,y1)-(x2,y2) is the left line, and (x3,y3)-(x4,y4) is
  1683. the right line.  The first thing to note is that in lines 40 and 46, 
  1684. Y=y2-y1+1.  This issue was discussed in the very first C=Hacking 
  1685. 3D-graphics article.  The problem is that although the line will be 
  1686. anatomically correct with DY=y2-y1, it will look silly.  The easiest way
  1687. to see this is to consider y2-y1=1, e.g. say we draw a line between
  1688. (0,10) to (50,11).  Ideally this line will consist of two line segments,
  1689. one from (0,10) to (25,10) and the other from (26,11) to (50,11).  But ifi
  1690. we use DY=1 we will have one line segment from (0,10) to (50,10), and a
  1691. single point at (50,11).
  1692.  
  1693. Adding one to DY is just a simple cheat.  Most of the time the lines will
  1694. look just fine, but lines which have a slope near one will come out a bit
  1695. wrong.  The other, accurate solution, which was used in the first
  1696. article, is more complicated to implement in this routine.  Adding one to
  1697. DY will also have a useful benefit which we shall shortly see.   
  1698.  
  1699. In line 50 above the boundaries of our object are drawn in, to check the
  1700. accuracy of the algorithm.
  1701.  
  1702. In lines 70-80 the right point is updated, then the thing is filled, then
  1703. the left point is updated.  This is because both lines are moving to the
  1704. right, e.g. they both have positive slope.  Think about how the line
  1705. segments will be drawn; in general, we want to draw from the left end of
  1706. the left line segment to the right end of the right line segment.  
  1707. (Sometimes this will look a little off where the two lines meet).
  1708.  
  1709. Since the left and right lines can each have either positive or negative
  1710. slopes, there are four possibilities: Plus-Plus, Plus-Minus, Minus-Minus,
  1711. and Minus-Plus.
  1712.  
  1713.    Plus-Plus:  Update right, fill, then update left
  1714.    Plus-Minus: Fill, update left, update right
  1715.    Minus-Minus:Update left, fill, update right
  1716.    Minus-Plus: Update left, update right, fill
  1717.    
  1718. If this is still confusing, try out the above program with various left
  1719. and right line segments, and these things will jump right out.
  1720.  
  1721. Now we need to think about implementing this in assembly.  Since this is
  1722. being done in hires 320x200, the x-coordinate requires two bytes, and the
  1723. y-coordinate requires one.  We also need another byte to store the
  1724. remainder portion of the x-coordinate.
  1725.  
  1726. The most glaring question is the calculation of dx/dy: somehow we need a
  1727. fast way of exactly dividing an eight bit number dy into a nine bit
  1728. number dx.  Recall that we always add one to dy, so that dy actually
  1729. ranges from 2 to 200.  Since the maximum value of dx is 320 or so, the
  1730. largest value of dx/dy that we can have is 320/2 = 160.  In other words,
  1731. both the integer and remainder part of dx/dy will fit in a byte.  Simply
  1732. adding one to dy makes life pretty easy at this end.
  1733.  
  1734. One very fast method of doing division is of course by using logarithms.
  1735. But they have a problem with accuracy.  One the other hand, one thing we
  1736. know how to do very quickly is multiplication.
  1737.  
  1738. This then is the plan: use logarithmic division to get an estimate for N,
  1739. the integer part.  Then calculate N*dy, compare with dx, and adjust the
  1740. integer part accordingly.                             
  1741.  
  1742. A quick reminder of how logarithms can be used for division:
  1743.  
  1744.    log(a/b) = log(a) - log(b)
  1745.    exp(log(x)) = x
  1746.  
  1747. thus
  1748.  
  1749.    a/b = exp(log(a)-log(b)).
  1750.  
  1751. How do we take the log of a 9-bit number?  We don't.  Instead, we
  1752. construct a table of f(x)=log(2*x), and use, not x, but x/2, as a
  1753. parameter.  Remember that the logarithms merely give an estimate to the
  1754. integer part.
  1755.  
  1756. Moreover, if the tables are constructed carefully we can insure that the
  1757. estimate for N is either exact or too small.  Thus we only need to check
  1758. for undershoots, which simplifies the calculation considerably.  In
  1759. particular, the tables were constructed as follows:
  1760.  
  1761.    10 DIM L1%(160), L2%(200), EX%(255): C=255/LOG(160)
  1762.    20 FOR I=1 TO 160
  1763.    30 L1%(I)=INT(C*LOG(I))
  1764.    40 NEXT
  1765.    50 FOR I=2 TO 200
  1766.    60 L2%(I)=INT(C*LOG(I/2)+0.5)
  1767.    70 NEXT
  1768.    80 FOR I=0 TO 255
  1769.    90 EX%(I)=INT(EXP(I/C))
  1770.    95 IF(I=129)OR(I=148)OR(I=153)OR(I=81)OR(I=98)THEN EX%(I)= EX%(I)-1
  1771.    100 NEXT
  1772.    110 L2%(3)=L2%(3)+1
  1773.  
  1774. The constant C is needed obviously to improve accuracy (log(160) simply
  1775. isn't a very large number).  Note that I divided the arguments of the
  1776. logarithms in half; instead of calculating 2*dx/dy I calculate dx/(dy/2),
  1777. which is of course the same thing.  This was done to make C work out.
  1778. By 'fixing' the tables in this manner, exactly 3927 calculations will
  1779. undershoot, which works out to about 6% of all possible calculations we
  1780. may perform.
  1781.  
  1782. The actual division routine works out pretty slick in assembly:
  1783.  
  1784.    DIVXY    MAC      ;Macro to compute 2*X/Y
  1785.             LDA LOG1,X  ;This is the division part
  1786.             SEC
  1787.             SBC LOG2,Y
  1788.             BCS CONT
  1789.             LDX #00     ;dx/dy < 1
  1790.             LDA ]1      ;LDA dx, since dx is exactly the remainder
  1791.             BCC L2
  1792.    CONT
  1793.             TAX
  1794.             LDA EXP,X
  1795.             TAX      ;X is now integer estimate
  1796.             STA MULT1
  1797.             EOR #$FF
  1798.             ADC #00     ;Carry is guaranteed set
  1799.             STA MULT2
  1800.             LDA ]1      ;ldxlo or rdxlo (i.e. low byte of dx)
  1801.             ADC (MULT2),Y
  1802.             SEC
  1803.             SBC (MULT1),Y  ;Calculate remainder
  1804.    L2       CMP ]2      ;ldy or rdy (i.e. ]2 = dy)
  1805.             BCC DONE
  1806.    L1       INX      ;Remainder is too large, so up int estimate
  1807.             SBC ]2      ;and subtract dy
  1808.             CMP ]2      ;Repeat until remainder<dy
  1809.             BCS L1
  1810.    DONE     <<<      ;Now X contains integer, A remainder
  1811.    
  1812. Do you see how it works?  First the initial guess N is calculated.  If
  1813. log(x) - log(y/2) is negative then dx/dy is less that one, so the
  1814. remainder is simply dx and the integer part is zero.  Otherwise,
  1815. R= dx - N*dy is calculated.  Since N always undershoots, dx-N*dy will
  1816. always be positive, so the high byte of dx isn't needed.  This quantity
  1817. R is the remainder, so if it is larger than dy simply increase the
  1818. integer estimate and subtract dy from R, and repeat if necessary.
  1819.  
  1820. The end result then is a 9-bit/8-bit divide which takes 52 cycles
  1821. in the best case.  Pretty neat, huh?  And quite adequate for our
  1822. purposes.
  1823.  
  1824. Wait just a minute there, bub... what about when dy=0?  Consider what
  1825. dy=0 means: it means that two vertices lie along the same line.  That in
  1826. turn means that the next vertex can be immediately skipped to.  That is,
  1827. simply move on to the next point in the list, be it to the right or to
  1828. the left, if dy=0.
  1829.  
  1830. Well, ah reckon that that just about completes the polygon fill routine.
  1831. To summarize: start at the bottom (top, whatever) of the polygon. 
  1832. Calculate the "slopes" of the right and left lines from that point.  
  1833. Update the coordinates, fill the in-between parts, and plot the 
  1834. end-sections.  Then update Y and keep going.  If another vertex is hit,
  1835. then recalculate the corresponding line.                       
  1836.  
  1837. Alert people may have noticed that this algorithm translates very nicely
  1838. to the 128's VDC chip.
  1839.  
  1840. I should probably briefly mention the pattern fills.  I use Y as an index
  1841. to a pattern table, so it was very natural to use 8x8 character patterns.
  1842. With different indexing of course more complicated patterns can be used.
  1843. Moreover, it dawned on me that animated patterns were just as easy as 
  1844. normal ones, so I tried to think up a few interesting animated patterns
  1845. (there are two in Polygonamy, each pattern is eight frames).
  1846.  
  1847. So that's the graphics part, more or less.
  1848.  
  1849. We ain't even CLOSE to being done yet.
  1850.  
  1851. @(A): 3D Code
  1852.       -------
  1853.       
  1854. Now it's FINALLY time to start writing the master program to control the
  1855. 3D world.  Luckily we have the BASIC program from waaaay up above to
  1856. work from.
  1857.  
  1858. First is to decide how angles will be measured.  The smart thing to do is
  1859. to let the angle variable vary between 0..127 or 0..255; that is, to
  1860. measure angles in units of 2*pi/128 (or 2*pi/256).  The reason this is
  1861. smart is because the angle is now periodic, wrapping around 256.  Angles
  1862. can be added together without checking for overflow, etc. (257=1, 258=2,
  1863. 259=3, etc.).  Note that in previous programs I did a very dumb thing
  1864. and let the angle variable vary from 0..119, so angles were measured in
  1865. three degree increments, and I had to place all sorts of checks into the
  1866. code.  Polygonamy uses angle increments of delta=2*pi/128.
  1867.  
  1868. Next there is the issue of cx=cx+20 instead of cx=cx+1.  The problem is
  1869. that if cx=cx+1 is used it takes forever to move around in the world.
  1870. Moreover, the objects get really small at around cx=5000.  What this
  1871. means is that in the assembly version we can use a single byte for cx,
  1872. and just treat each unit of cx as 20 "real world" units.  That is, in
  1873. the assembly program, we will keep track of cx/20 instead of cx.
  1874.  
  1875. Sort-of.
  1876.  
  1877. Consider the rotation which takes place when we turn left or right: the
  1878. world is rotated through an angle delta=2*pi/128, so the calculation is:
  1879.  
  1880.    blah= cdel*cx + sdel*cz.
  1881.    cz= -sdel*cx + cdel*cz
  1882.  
  1883. The problem is that sin(2*pi/128)=0.049 and cos(delta)=0.9988, which
  1884. means that, in practice, cdel*cx=cx.  Equally bad is that sdel*cz is very
  1885. small when cz starts to get small (e.g. 10*sdel = 0.49).  The result of
  1886. this is that objects close to the origin (e.g. us) will not be rotated at
  1887. all!
  1888.  
  1889. Thus the centers need to be calculated more accurately.  In particular, a
  1890. second byte is needed to store the 'decimal' part of the center.  To be
  1891. precise, this second byte will contain the decimal part of the center
  1892. times 256.  This way we can add and subtract remainders and any over- or
  1893. underflows will then affect the integer parts cx,cy,cz.
  1894.  
  1895. Very quickly we should decide how to represent remainders of negative
  1896. numbers.  A number like -1.5 can be represented as -1 - 0.5, but it can
  1897. just as well be represented as -2.0 + 0.5.  By using the second method
  1898. remainders are always positive, and that's the smart way to do things (if
  1899. nothing else it lets the remainder be a fraction of 256, instead of a
  1900. fraction of 128).  It's also the way any computer will round: type
  1901. INT(-1.5) and see what happens.
  1902.  
  1903. further question arises about how to represent the centers, specifically, 
  1904. how do we represent an object which is behind us, e.g. has a negative 
  1905. value for cx.  The normal way to represent negative numbers is of course 
  1906. to use 2's complement notation, but this has some disadvantages.  One of 
  1907. them is multiplication: recall that in an earlier code some really fancy 
  1908. footwork needed to be done just to be able to multiply numbers between 
  1909. -64..64, and we certainly want the centers to range over more numbers
  1910. than that.  This gets worse if we decide to use more bits to represent
  1911. the centers, as we must do if a larger world is constructed.
  1912.  
  1913. Moreover, Polygonamy is an excuse for testing new and different ideas and
  1914. investigating their strengths and limitations, so why not try something
  1915. different.  As I look through my notes I'm not really sure what motivated
  1916. this choice, but how about the following: let's add 128 to all of our
  1917. numbers.(I think this is called excess-128 notation).  -2 will be
  1918. represented as 126, -1 will be represented as 127, six will be
  1919. represented as 134, etc.
  1920.  
  1921. Shifting between the excess numbers and 'real' numbers is as simple as
  1922. EOR #128.  Recall that to multiply two numbers, let f(x)=x^2/4, so that
  1923. a*b = f(a+b) - f(a-b).  In the new system:
  1924.  
  1925.    xo = 128+x
  1926.    yo = 128+y
  1927.  
  1928. which means:
  1929.  
  1930.    xo+yo = 256 + (x+y)
  1931.    256+xo-yo = 256 + (x-y).
  1932.  
  1933. The 256 added above can be thought of as the carry bit.  What this means
  1934. is that all that is needed is to construct a single function,
  1935.   
  1936.    f(x) = (x-256)^2
  1937.  
  1938. where x=-255..255.  We can now very quickly multiply signed numbers in
  1939. the range -128..128, and with just a single (albeit 512 byte) table,
  1940. using essentially the same multiplication procedure as before.
  1941.  
  1942. Now the downside of this method: adding and subtracting excess-128
  1943. numbers, and in particular checking for overflow.
  1944.  
  1945.    xo+yo = 256 + (x+y)
  1946.    if x+y >= 128 then we have overflow
  1947.    if x+y < -128 then we have underflow
  1948.  
  1949. which implies:
  1950.  
  1951.    xo+yo >= 256+128  implies overflow
  1952.    xo+yo < 128   implies underflow
  1953.  
  1954. with similar results for subtraction.  Note also that after every
  1955. addition or subtraction 128 needs to be either added or subtracted from
  1956. the result, which either way corresponds to an EOR #$80.  So it's a
  1957. little more work to add numbers in this system.  (Of course, adding
  1958. normal numbers to excess-128 numbers is no problem, so INC and DEC work
  1959. fine).
  1960.  
  1961. Back to rotations.  The most obvious thing to do is to create two tables:
  1962.  
  1963.    f(x) = (x-128)*cos(delta) + 128
  1964.    g(x) = (x-128)*sin(delta) + 128
  1965.  
  1966. but remember that the remainders are also needed:
  1967.  
  1968.    fr(x) = 256*(remainder((x-128)*cos(delta)))
  1969.    gr(x) = 256*(remainder((x-128)*sin(delta)))
  1970.  
  1971. Since remainders are always positive none of this excess-128 junk is
  1972. needed.  Note that we could also let f(x) and g(x) be 2's-complement
  1973. tables, then convert from two's-complement into excess-128 after
  1974. performing additions etc.  The conversion is, what do you know, EOR #$80.
  1975. This is the smarter thing to do, and an even smarter thing to do is to
  1976. let the cosine table (f(x) above) to be in excess-128 format, and the
  1977. sine table g(x) in 2's complement.  This way the numbers can be added
  1978. as normal, and no conversion need take place:       
  1979.  
  1980. * Compare to BaSiC subroutine rotl: above
  1981.  
  1982.    ROTL
  1983.             INC THETA
  1984.             LDY #NUMOBJS   ;Y indexes the object
  1985.             DEY
  1986.    
  1987.    :LOOP    LDX CX,Y ;center coordinate
  1988.             LDA CDEL,X  ;CDEL = f(x) above
  1989.             LDX CZ,Y
  1990.             CLC
  1991.             ADC SDEL,X
  1992.             STA TEMP ;t1 = ci+si
  1993.             LDA CXREM,Y
  1994.             CLC
  1995.             ADC SDELREM,Y  ;Add remainders
  1996.             BCC :CONT1
  1997.             INC TEMP
  1998.             CLC
  1999.    :CONT1   LDX CX,Y
  2000.             ADC CDELREM,X
  2001.             BCC :CONT2
  2002.             INC TEMP
  2003.    :CONT2   STA CXREM,Y
  2004.    
  2005.             LDX CZ,Y
  2006.             LDA CDEL,X
  2007.             LDX CX,Y
  2008.             SEC
  2009.             SBC SDEL,X
  2010.             STA TEMP2   ;t2=cz-si
  2011.             LDA CZREM,Y
  2012.             SEC
  2013.             SBC SDELREM,X
  2014.             BCS :CONT3
  2015.             DEC TEMP2
  2016.    :CONT3   LDX CZ,Y
  2017.             CLC
  2018.             ADC CDELREM,X
  2019.             BCC :CONT4
  2020.             INC TEMP2
  2021.    :CONT4   STA CZREM,Y
  2022.             LDA TEMP2
  2023.             STA CZ,Y
  2024.             LDA TEMP
  2025.             STA CX,Y
  2026.             DEY
  2027.             BPL :LOOP
  2028.    
  2029. Well, that takes care of two lines of BASIC code :).  As it turns out,
  2030. using a single byte for the remainder does a pretty good job of holding
  2031. the number.  Rotating by 360 degrees one way, then rotating back again,
  2032. produces a center which is within a few decimal places of the starting
  2033. value.
  2034.  
  2035. Next up: projections.  The projection calcuation is:
  2036.  
  2037.    Proj(P) = d*(P+C)/(px+cx)
  2038.  
  2039. where P=(px,py,pz) and C=(cx,cy,cz).  In terms of the implementation, we
  2040. want to calculate:
  2041.  
  2042.    d*((P-128) + s*(C-128)) / ((px-128) + s*(cx-128))
  2043.  
  2044. where s=20, to translate C into the 'real world'.  To calculate this,
  2045. consider the following function:
  2046.  
  2047.    g(x) = r*d / (s*((px-128)/s + cx-128)) + 128
  2048.  
  2049. where r is some scaling factor.  The projection calculation then becomes:
  2050.  
  2051.    1/r*( (g-128)*(P-128) + s*(g-128)*(C-128) )
  2052.  
  2053. Thus we need some more tables, one of 1/(4r) * (256-x)^2, the other of 
  2054. s/(4r) * (256-x)^2, to do the multiplication.  Furthermore a table of 
  2055. (x-128)/s would be pretty handy, and finally we need a table of 
  2056. g(x) = r*d/(s*(x-128)) + 128.                                     
  2057.  
  2058. The general outline of a program would be:
  2059.  
  2060.    Get keypress
  2061.    1- If translate, then update all cx's (just some INCs and DECs)
  2062.    2- If rotate left or right, then rotate world
  2063.    3- Update angles for global & local rotation matrix (e.g. theta)
  2064.    4- Figure out which objects to display/construct a list
  2065.    5- Call each object in turn
  2066.    6- Update bitmap: clear out remaining garbage and swap bitmaps
  2067.  
  2068. Numbers 1 and 2 are done.  In number three, by global matrix I mean the
  2069. object rotation that results from us turning left or right.  By local
  2070. rotation I mean rotations independent of whether or not we turn.  The
  2071. local rotation allows e.g. the octahedron to spin around in Polygonamy.
  2072.  
  2073. Figuring out which objects to display is easy: just check to make sure it
  2074. lies within the viewing cone/pyramid, that we are not too close, etc.  If
  2075. an object is to be displayed, it needs to be placed in a list.  I
  2076. constructed the list to make sure that objects which are farther away are
  2077. drawn first; that way objects can overlap one another correctly.  This
  2078. was done via a simple insertion sort -- i.e. bump up objects in the list
  2079. until the right spot is reached to insert the object.
  2080.  
  2081. We have most of the tools to deal with #5.  Handling an object consists
  2082. of rotating and projecting it, then displaying it.  Rotation is the same
  2083. as it has always been, albeit now involving sixteen bits, and projection
  2084. is described above.  Then each polygon needs to be drawn, by sticking the
  2085. points of the polygon into the polygon list, setting up the fill pattern
  2086. and the pointer to the minimum Y-value, and calling the polygon fill
  2087. routine.  Of course, if the face is hidden then we certainly don't want
  2088. to plot it.
  2089.  
  2090. The minimum y-value can be found very easily while inserting the points
  2091. into the point list -- just keep track of ymax and compare to each point
  2092. as it is inserted.
  2093.  
  2094. We have discussed several methods of calculating hidden faces --
  2095. cross-product, rotated normal, parallel faces -- each of which involves
  2096. looking at a vector normal to the face, and either projecting it or
  2097. taking the dot product with a vector going to the origin.  What a big
  2098. pain in the butt, especially since values can be sixteen-bits, etc.
  2099.  
  2100. Did you ever stop to wonder about what happens to all the previous
  2101. polygon-fill calculations if the point-list is entered in reverse order?
  2102. Quite simply, left -> right and right -> left.  And what happens when a
  2103. face is invisible?  The polygon is turned away from our eye.  The points
  2104. in the polygon, which go counter-clockwise around the polygon, will go
  2105. clockwise when the polygon is turned around.  (I should point out that at
  2106. least in my code the points on the polygon are actually done in
  2107. clockwise-order, since projection reverses the points).
  2108.  
  2109. So, we have hidden-faces already built-in to the polygon plot routine!
  2110. In essence, we simply don't plot any polygon which the routine will freak
  2111. out on.  We can of course be systematic about this; within the plot
  2112. routine:
  2113.  
  2114.    - Calculate the left and right lines.
  2115.    - Take a trial step along the left and right lines
  2116.    - If xleft < xright then we are OK, otherwise punt.
  2117.  
  2118. In principle we only need to do this on the first calculation, and use
  2119. some properties of the lines to make things easier (for instance, if the
  2120. left line is moving left and the right line is moving right, and they
  2121. emanate from the same point, we know the polygon is visible).
  2122. Unfortunately, nasty situations can arise, for instance when the left and
  2123. right slopes have the same integer parts.  So a check needs to be placed
  2124. within the fill code to make sure the left point doesn't get ahead of the
  2125. right point.  This is unfortunate, as every cycle counts in the fill
  2126. code, but luckily there is (was) a natural place to put in a quick check.
  2127.  
  2128. All that is left then is #6: run through the fill table, and clear any
  2129. lines that still have old junk in them.  Since I used two bitmaps as a
  2130. double-buffer, all that is left is to swap the bitmaps, and do it all
  2131. again.
  2132.  
  2133. Et voila.
  2134.  
  2135. @(A): Analysis and Conclusions
  2136.       ------------------------
  2137.  
  2138. As you can see, the program is not without its flaws.  The biggest one,
  2139. I think, deals with the projection.  Recall that I calculate px/s, where
  2140. s=20, and add it to cx.  My feeling was that px was going to be very
  2141. small compared with cx, and so not modify the projection by much.  But
  2142. either this is a bad assumption, or the rotations are all screwed up,
  2143. because certain rotations look a bit goofy.  For instance, when you walk
  2144. up close to the octahedron it starts to get jumpy, or wobbly.  I note
  2145. further that when you are far away from an object it looks much better,
  2146. so that might be a way to fudge around the problem (e.g. make the value
  2147. of d in the projection much larger).
  2148.  
  2149. Speaking of rotations, the 'funky shake' which used to plague the old
  2150. programs has now been fixed.  For instance, a rotation in the y-direction
  2151. would work well but at some point it would appear to start rotating
  2152. backwards, then start going the right way again.  The problem was due to
  2153. an overflow in the calculation of the rotation matrix, in a term that
  2154. looked like(sin(t1) + sin(t2) - sin(t3) - sin(t4))/4, and the solution is
  2155. to split such terms into two, e.g. (sin(t1)+sin(t2))/4 - 
  2156. (sin(t3)+sin(t4))/4.
  2157.  
  2158. Speaking further of rotations, I find the current system of rotation and
  2159. projection unsatisfying, in particular too slow.  Notice how much the
  2160. program slows down when all three objects are visible; some 40 points
  2161. are being rotated, both locally and globally, at this point.  It is
  2162. possible to reduce the number of matrix multiplications from 9 to 8 (and
  2163. even lower, with lots of extra overhead), but I find this unsatisfying.
  2164. A better method is needed...
  2165.  
  2166. There is another bug somewhere in the global rotations which sometimes
  2167. causes the objects to wander around -- occasionally I can get the ship or
  2168. the octahedron to move close to the pyramid.  Also, when you are really
  2169. close to an object and turn, you might notice the curious effect of the
  2170. object rotating by small amounts, and then jumping position by a large
  2171. amount.  This is due to the 'units of 20' that are used in the program;
  2172. the remainder part of (cx,cy,cz) needs to be used here, and then the
  2173. display will be smooth as well.
  2174.  
  2175. Of course, if multicolor mode was used many of the calculations would be
  2176. much simpler, since the screen x-coordinate would only require one byte
  2177. instead of two.
  2178.  
  2179. The program should be made more efficient memory-wise of course.  Shoving
  2180. the fill routines for each buffer together would help out, and a system
  2181. for rotating points out of a list, similar to that used in the last 3D
  2182. program, would greatly streamline things (although it would be a tad
  2183. slower).
  2184.  
  2185. There is still a minor bug or two in the fill routine, which causes
  2186. little blue chunks to be taken off the ends of some polygons, but I
  2187. didn't feel like tracking it down.
  2188.  
  2189. Note that although Polygonamy only lets you run around in a plane,
  2190. running around in a full three dimensions is quite simple to add.  And,
  2191. although there are only three objects in the world, it is all set up to
  2192. deal with a lot more.  In summary, I see no major problems standing 
  2193. in the way of doing reasonably fast 3D graphics on the 64. 
  2194.  
  2195. The object file for this article is available in "Hacking the Code"
  2196. (Reference: code, SubRef: polycode) found elsewhere in this issue.
  2197.  
  2198. ============================================================================
  2199.  
  2200. @(#)usenet: UseNuggets
  2201.   
  2202. COMP.SYS.CBM:  The breeding ground of programmers and users alike.  Let's
  2203. see what topics are showing up this month:
  2204.  
  2205. @(A): What is the HECK is BCD?
  2206.    As most ML programmers know, the 65XX CPU line has a arithmetic mode
  2207.    called "decimal mode", and is used to manipulate Binary Coded Decimal
  2208.    numbers (BCD).  BCD numbers treat each nybble as a decimal digit. 
  2209.    Possibel values for a byte than ar $00 to $99.  Some fool asked on the
  2210.    group what earthly use BCD has on the 65XX CPU.  Well, among other things,
  2211.    Willem-Jan Monsuwe shared this tidbit:
  2212.    
  2213.       I recall someone asking what the use of BCD (Binary Coded 
  2214.       Decimal) was.  I have here a 99-byte program that uses it to 
  2215.       print out a number stored in the memory in decimal, with a 
  2216.       maximum of more than 10^500 digits, Within 5 seconds ;).  
  2217.       What's the use ??  Well, you can impress your friends by 
  2218.       calculating the answer to the chessboard-problem ( 2^64 
  2219.       - 1 or 0xFFFFFFFFFFFFFFFF ) within 0.06 of a second.  Oh, 
  2220.       and the maximum is pretty easy to overcome, with a slight 
  2221.       code change, if anyone needs numbers greater than, oh, 
  2222.       509 digits.. ;) 
  2223.                      
  2224.       *        = $1000
  2225.       
  2226.       SNUM     = $1100
  2227.       BUFF     = $1200
  2228.       
  2229.       PRINT    = $FFD2
  2230.       
  2231.       SNUMPTR  = $FB
  2232.       SNUMBF   = $FC
  2233.       BUFFEND  = $FD
  2234.       
  2235.                  LDA #0
  2236.                  TAX
  2237.       CLRBUFF    STA BUFF,X
  2238.                  INX
  2239.                  BNE CLRBUFF
  2240.                  SED
  2241.                  STA BUFFPTR
  2242.                  LDY #210
  2243.                  STY SNUMPTR
  2244.       BYTELOOP   LDA SNUM,Y
  2245.                  STA SNUMBF
  2246.                  LDY #8
  2247.       BITLOOP    ASL SNUMBF
  2248.                  LDX #0
  2249.       ADDLOOP    LDA BUFF,X
  2250.                  ADC BUFF,X
  2251.                  STA BUFF,X
  2252.                  INX
  2253.                  BCS ADDLOOP
  2254.                  CPX BUFFEND
  2255.                  BCC ADDLOOP
  2256.                  STX BUFFEND
  2257.                  DEY
  2258.                  BNE BITLOOP
  2259.                  DEC SNUMPTR
  2260.                  LDY SNUMPTR
  2261.                  CPY #$FF
  2262.                  BNE BYTELOOP
  2263.                  CLD
  2264.                  LDA #13
  2265.                  JSR PRINT
  2266.                  DEX
  2267.                  LDA BUFF,X
  2268.                  AND #$F0
  2269.                  BEQ LOWNYB
  2270.       PRINTLOOP  LDA BUFF,X
  2271.                  LSR
  2272.                  LSR
  2273.                  LSR
  2274.                  LSR
  2275.                  CLC
  2276.                  ADC #48
  2277.                  JSR PRINT
  2278.       LOWNYB     LDA BUFF,X
  2279.                  AND #$0F
  2280.                  CLC
  2281.                  ADC #48
  2282.                  JSR PRINT
  2283.                  DEX
  2284.                  CPX #$FF
  2285.                  BNE PRINTLOOP
  2286.  
  2287. @(A): Commodore's Can't Compute! (or can they?)
  2288.    OK, try the following on your beloved 128:
  2289.  
  2290.       print 23.13 - 22.87   hit RETURN
  2291.       
  2292.       Do you get .260000005?
  2293.       
  2294.    The resuling thread after this question was posed started to lean in the
  2295.    direction of attacking the arithmetic units of BASIC in the Commodore
  2296.    8-bit machines.  Then an eloquent post from Alan Jones 
  2297.    (alan.jones@qcs.org) started to set the record straight.  We can't
  2298.    express it any better than Alan:
  2299.    
  2300.       Recently, the C64/128 floating point arithmetic has been maligned
  2301.       here.  The C64/128 has good floating point math.  It uses 5 byte reals
  2302.       with a 4 byte (32 bit) mantissa.  There are no bugs in the basic FP
  2303.       arithmetic.  The reals ARE limited in range and precision.  They are
  2304.       more useful than compters using 32 bit reals, but not up to IEEE
  2305.       standard arithmetic.  IEEE FP arithmetic (double and extended
  2306.       precision...) would be much slower than our existing FP routines.  Of
  2307.       course it might be possible to interface a hardware FPU to the new
  2308.       Super64/128CPU (65816).
  2309.       
  2310.       The other C64/128 FP routines, such as SIN, EXP, and functions that use
  2311.       them are not accurate to full 32 bit FP precision.  When used with
  2312.       care, they are often accurate enough for engineering work.
  2313.       
  2314.       The most annoying inaccuracy may be the conversion between binary FP
  2315.       and decimal for I/O.  BASIC only prints 9 decimal digits of a FP
  2316.       number, but our binary FP number has about 9.6 decimal digits of
  2317.       precision.  What you see is not what you have!  Of course there are
  2318.       some simple tricks that you can use to print the FP number with more
  2319.       decimal precision, and you could do I/O using HEX notation.  If you
  2320.       save intermediate results for later use, make sure you write the FP
  2321.       values as binary rather than ASCII (converted to decimal).
  2322.       
  2323.       If you do accounting type stuff with dollars and cents, using binary FP
  2324.       with its limited precision and rounding can be anoying.  If your
  2325.       results are off one penny, all of your work will be suspect.  Our 6502
  2326.       family of CPUs also has decimal arithmetic.  It can do decimal
  2327.       arithmetic exactly, although you may have to program it yourself.  I
  2328.       think the Paperclip word Processor will do simple calculations with up
  2329.       to 40 decimal digits of precision.
  2330.       
  2331.       If you are using 64+ bit FP you can compute some things in a fast and
  2332.       sloppy manner.  Some programs that work OK on an IBM PC or workstation
  2333.       need more careful attention when coded for a C64/128.
  2334.       
  2335.       Some numbers can not be represented exactly in binary FP formats of any
  2336.       precision.  If you want to calculate:
  2337.       
  2338.         a:=(1/3)*(1/5)*(1/7)*(1/11)
  2339.       
  2340.       You should code it as:
  2341.  
  2342.         a:=1/(3*5*7*11)
  2343.       
  2344.       Aside from being faster, it is more accurate.
  2345.        
  2346.       There are many tips for preserving numerical accuracy in computations.
  2347.       There are often interesting tradoffs between computation speed, memory
  2348.       usage, and accuracy and stability.  There are even some C64/128
  2349.       specific tips.  (e.g. we usually store a real value in 5 bytes of
  2350.       memory but push it onto a stack as 6 bytes when we want to use it.)
  2351.       
  2352.       This is not intended to be a Commodore FP tutorial.  It is reminder
  2353.       that the C64/128 can be used for "heavy math", and there are no bugs
  2354.       in the Commodore +, -, *, /, Floating Point arithmetic routines.  It
  2355.       uses 32 binary bit mantisa FP reals with proper rounding.
  2356.       Simple examples can always be contrived to demonstrate a perceived FP
  2357.       bug by computer illiterates(?).
  2358.       
  2359.    Alan got his dig in at the end there.  That post, and others like it,
  2360.    pretty much squelched the arithmetic discussion.  But, as is usually the
  2361.    case, we all learned a neat trick along the way.  Peter Karlsson shared
  2362.    his easy way of determining whether his programs are running on a C64 or
  2363.    C128 by issueing the following statement:
  2364.  
  2365.       C=64+64*INT(.1+.9)
  2366.  
  2367.    Since the 64 and 128 differ ever so slightly in their arithmetic
  2368.    routines, the above line gives 64 on a C64 and 128 on a C128.
  2369.    
  2370. @(A): We need another OS!
  2371.    It all started when Benjamin Moos posted a message in the newsgroup
  2372.    mentioning that he had been off the net for a while but was returning 
  2373.    and wondered whether anyone would want him to finish work on a C++ based
  2374.    comiler for the GEOS 2.0 environment.  Of course, everyone was for that,
  2375.    but Moos continued on, asking if there was any interest in an alternate
  2376.    OS for the 64 or 128.  Moos mentioned that he had been also working on
  2377.    Common Graphic OPerating Environment (CGOE), and was thinking about
  2378.    finishing the project, which would provide a C= graphics character
  2379.    based graphic windowing system that would allow all 64 programs to run
  2380.    in the 128 80 column screen in 40 column windows.  
  2381.    
  2382.    Well, that brought out some friendly debate, to state the obvious. Part
  2383.    of the group posted words of encouragement, noting that we need to
  2384.    support those programming for the environment.  The other half of
  2385.    the camp echoed the words of Patrick Leung, who expressed concern that
  2386.    there are many programmers in the arena that are doing the same thing
  2387.    separately.  He encouraged programmers to consolidate features and code
  2388.    bases to arrive at robust full-featured programs instead of fragile bare-
  2389.    bones applications that single programmers can't support. ACE, Craig
  2390.    Bruce's UNIX-like OS detailed in earlier C=Hacking issues, was brought
  2391.    up by some, who asked that programmers heed Leung's advice and build
  2392.    modules for the already supported ACE environment.
  2393.    
  2394.    Perhaps J. Shell has the best idea, as he is planning to set up an
  2395.    interactive WWW site to allows programmers to work with him to build
  2396.    COMMIX System II (CX2).  The site will allow programmers to bring new
  2397.    ideas to the table and have them rapidly incorported into the design.
  2398.    We'll see if Mr. Shell can deliver on this neat idea.
  2399.    
  2400.    Going full circle, Benjamin Moos reponded to some of the posts, saying
  2401.    that the OS work was going to be placed on the shelf for now, as many
  2402.    had expressed interest in the C++ like compiler.  However, he did say 
  2403.    that work would begin again at a later date, but no decision was made
  2404.    as to how he will proceed.
  2405.    
  2406. @(A): The "More Power" Swiftlink
  2407.    Ever striving to squeeze the most performance out of his C128 system,
  2408.    Craig Bruce modified his Swiftlink and lived to tell about it in the
  2409.    newsgroup.. Basically, after researching the data sheets for the 6551
  2410.    ACIA IC used in the SL, Craig noted that Dr. Evil Labs (the original
  2411.    creators of the SL) had used a double speed crystal to up the 19,200
  2412.    bps maximum in the ACIA to 38,400 bps.  The IC claims that any baud
  2413.    rate up to 125,000bps can be achieved with the IC, given the correct
  2414.    crystal frequency.  Well, another feature of the 6551 is to use the 
  2415.    crystal frequency/16 as the bps rate, which is 230,400 bps or the 
  2416.    stock crystal.  Too fast for the IC.  However, by replacing the 
  2417.    crystal ( a 3.6864 MHz unit) with a 1.8432 MHz unit, the 1/16 speed
  2418.    becomes 115,200.  That speed, less than 125,000 bps, is the standard
  2419.    top frequency for IBM UARTs and is supported by most newer modems.  
  2420.    Craig verified that his 2MHz 128 can keep up with the extra data
  2421.    that his modofoed SL allows him to receive, but not always.  he
  2422.    claims that every once in a while, the systm gets choked up and 
  2423.    crashes, so he is working on solutions.  Understandably, one will need
  2424.    very tight terminal program code to keep up with this speed, but it
  2425.    will fit nicely with the SuperCPU.
  2426.    
  2427.    As with all things, there is a downside in that 19,200 becomes the
  2428.    next lower bps rate.  38,400 is gone forever.  Craig speculated that
  2429.    perhaps a switch could be installed, but wasn't sure of the effects.
  2430.    
  2431. @(A): The Eternal Problem
  2432.    Although this didn't receive much discussion, C=Hacking feels many users
  2433.    can relate. How many have ever went into the local CompUSA of local
  2434.    computer store and asked to look at modems, printers, or SCSI drives, 
  2435.    only to hear the dreaded laugh and chide that you should "buy a REAL
  2436.    computer", or watch the quizzical look of the sales person as they exclaim
  2437.    "You can't hook that up to a Commodore!"  We particularly enjoyed the
  2438.    ending to the lament that appeared in the newsgroup:
  2439.    
  2440.       When someone keeps an old car around, babies it, works on it,
  2441.       adds to it, drives it around in style, no one says "Look at 
  2442.       this dummy driving an out-dated gas guzzler that can't even do 
  2443.       80, and gets atrocious gas mileage.  The frame is archaic.  
  2444.       The windows aren't electric. Why doesn't he upgrade?".  Nah.. 
  2445.       they are 'enthusiasts of classic automobiles'.
  2446.  
  2447.       Well, ... we are "enthusiasts of a classic computer".
  2448.  
  2449. ============================================================================
  2450.  
  2451. @(#)fido: FIDO's Nuggets
  2452.  
  2453. The CBM and CBM-128 FIDONet echoes.  The place where Commodore users
  2454. unite.  Let's what things they discussed over the past month or two:
  2455.  
  2456. @(A): UNZIP 2 or not UNZIP 2?
  2457.    For a while now, Commodore users have been able to uncompress
  2458.    archives created with the popular PKZIP 1.01 compression program
  2459.    by PKWare or one of its clones.  Well, PKWare upped the ante and
  2460.    upgraded the PKZIP product to version 2, and that left a bunch of
  2461.    Commodore users compressed!  The easy solution is to ask all
  2462.    archive creators to not use version 2 of the ZIP product, but that
  2463.    presents a problem.  Most of the FIDONet crowd reads their mail 
  2464.    offline via popular programs like QWKIE 3.1 on the 64 or QWKRR128
  2465.    4.3 on the 128.  The programs work by retrieving a COMPRESSED
  2466.    packet of news and mail from a BBS.  Well, it turns out that BBS
  2467.    systems have migrated over to the new version of ZIP, and some
  2468.    refuse to offer ZIP version 1 as an optional compression method
  2469.    for retrieval packets.  So, the FIDONet crowd, including David
  2470.    Schmoll and others, have been working on or searching for a way
  2471.    to bring PKZIP 2 functionality to the 64.  Some thought it was a
  2472.    done deal when a FIDNetter contacted Info-Zip, the authors of a 
  2473.    free clone of PKZIP 2 by the same name.  They were told the source
  2474.    code was available.  The catch, it is written in C, and so far, 
  2475.    no compilation on the 64 or 128 has been successful.  
  2476.      
  2477. @(A): QWKIE v3.1 FREE!
  2478.    Many C64 users have delighted over the use of QWKIE v3.1 to read
  2479.    offline news and mail.  However, many had been unable to register
  2480.    the product.  The mystery was solved as of late a letter by the
  2481.    author was read that stated that he was ceasing support for the
  2482.    product and had placed it into the public domain.  As well,
  2483.    interested programmers could contact him about source code.  So,
  2484.    QWKIE FREE, a patched version of the program that is marked as
  2485.    registered, was uplodade to the many CBM BBS systems for users to
  2486.    enjoy.
  2487.  
  2488. @(A): That Darn Internet!
  2489.    As of late, many FIDONet regulars have been diappointed in the 
  2490.    trafiic flow on the CBM echoes.  They blame the growing
  2491.    popularity of the Internet as one reason the amount of messages
  2492.    has dwindled.  Almost immediately, reasons why FIDONet is still
  2493.    useful started popping up in the echoes.  Many claim that the
  2494.    Internet and FIDONet are complementary for the Commodore user, and
  2495.    that both resources are needed.  Others, however, stressed that
  2496.    FIDONet is still the most useful.  While C=Hacking isn't going
  2497.    to cast a vote here, we do hope that interest in the echoes stays
  2498.    high, as some only have access to FIDONet, and Commodore support
  2499.    should be on every network.
  2500.  
  2501. @(A): Let's Randomize
  2502.    Some soul on the echo was looking for a way to generate a random
  2503.    number from 2 to 350.  Well, always eager to help, many FIDONetters
  2504.    came to the rescue, with varying degrees of complexity.
  2505.  
  2506.    The first post, by Ken Waugh, included the text from one of
  2507.    Rick Kepharts WWW Site pages that explained, in two BASIC lines or
  2508.    less, how to create a set of 255 nonrepeating random numbers.                                  
  2509.  
  2510.    Then, ever the guru, George Hug, of 2400 bps on a 64 fame, described
  2511.    a method to find random numbers based on "linear maximal length
  2512.    shift registers", complete with 3 part article on the method.  Wow!
  2513.    needless to say, the method looks promising, but was probably more
  2514.    than what the original author was looking for.  Nonetheless, the
  2515.    treatise looks worthy of inclusion in an upcoming C=Hacking issue.
  2516.  
  2517. @(A): Catch the Wave!
  2518.    By now, most know that Maurice Randall, the author of GeoFAX, has been
  2519.    working on a GEOS telecommunications program that will operate at the
  2520.    14,400 bps or better mark.  It's been discussed in both USENET and
  2521.    FIDONet before, but Gaelyne Moranec reopened the discussion with a 
  2522.    statement that World Wide Web page viewing support might possibly
  2523.    be incoporated and under test.  Mr. Randall was hoping to add such
  2524.    support at some time, but it was unclear when.  It looks like sooner
  2525.    rather than later.
  2526.  
  2527. @(A): Who's First?
  2528.    Rod Gasson posed an interesting question on FIDONet a while back.  He
  2529.    asked which CPU was in control of the 128 when it is first powere up.
  2530.    The abvious answer of "the 8502" was given many times over, but Rod
  2531.    finally noted that it is, in fact, the Z-80 in the system that gains
  2532.    control of the system first.  Herman Yan supplied the relevant page 
  2533.    from the C128 Programmer's Reference Guide that explains the
  2534.    reasons.  If you want to know more, check out page 576 in the manual.
  2535.    
  2536. @(A): Desterm Confusion
  2537.    Many in the 128 arena use a telecommunications program called Desterm,
  2538.    by Matt Desmond.  At present, there are two versions of the shareware
  2539.    application out, 2.00 that works on all drives except the RAMLink, and
  2540.    2.01 that works with RAMLink, but has bugs not present in 2.00.  So,
  2541.    which to use?  That questions gets asked in verious forms in the echoes
  2542.    repeatedly.  That, coupled with the inability to find Mr. Desmond for
  2543.    a while, the supposed hand-over of the code to Steve Cuthbert, and the
  2544.    recent emergence of Matt (Reference: news) added to the confusion.  The
  2545.    current thinking is that Matt will be working on a new release of
  2546.    Desterm that will include CTS/RTS support (the present version only
  2547.    supports XON/XOFF flow control) and some bug fixes.  Somehow, the
  2548.    rumor that Matt will add Z-modem capabilities keeps pooping up, but
  2549.    Matt has denied any such work.  He merely doesn;t see a need, since
  2550.    add in modules can be created to do this.   
  2551.  
  2552. So, that gives you a glimpse into the world of FIDO, the wonder dog of
  2553. networks.  C=Hacking laments that their own FIDO feed has been
  2554. experiencing problems as of late, so we too may have missed some juicy
  2555. tidbits.  We'll catch them later on, though.
  2556.  
  2557. Here, boy....
  2558.  
  2559. =========================================================================
  2560.  
  2561. @(#)cmdcpu: Underneath the Hood of the SuperCPU
  2562.             by Jim Brain   
  2563.  
  2564. Does your mind go blank when you hear about the SuperCPU?  With all the
  2565. mention of it in magazines and newsletters, are you left wondering how
  2566. much of the discussion is hype and how much is true?  Are you worried
  2567. that this latest attempt is just another design destined for failure
  2568. like the others before it?  Well, if so, then you're not alone.  With 
  2569. the reputation accelerator cartridges and their manufacturers have 
  2570. acquired over the years, you are wise to be concerned.  Judge for
  2571. yourself, as we peer under the hood of the Creative Micro Designs
  2572. SuperCPU accelerator cartridges.
  2573.  
  2574. Note:  The information contained in this article has been gleaned from
  2575. talks with CMD, Mr. Charlie Christianson's post to comp.sys.cbm, 
  2576. responses to USENET posts by Mr. Doug Cotton, and information from Commodore
  2577. World Issue #12.  While general information is not likely to change, 
  2578. some details discussed in this article may differ slightly from those
  2579. incorporated in the final product.
  2580.  
  2581. @(A): What's An Accelerator?
  2582.  
  2583. Did you know a Commodore 64 CPU executes things at 1 MHz?  A tiny clock
  2584. inside the 64 ticks off 1 million "cycles" per second, and instructs
  2585. the CPU to move forward one cycle at a time.  The CPU, in turn, 
  2586. either executes an internal operation, reads from memory, or writes
  2587. to memory during that cycle.  These operations are concatenated to
  2588. form funtions, which is the smallest piece of work a programmer can
  2589. ask the CPU to perform.  These function are called instruction, and 
  2590. take an average of 3 cycles each to perform.  So, the typical C64
  2591. CPU does 333,333 things a second.  The C128 fares a bit better, as it
  2592. can run twice as fast when in "fast" mode.  In either case, there is
  2593. an upper bound on the amount of useful work each CPU can do in a
  2594. amount of time.  
  2595.  
  2596. An accelerator increases that amount of work done by substituting a 
  2597. faster CPU and clock speed for the 1 MHz 64 CPU.  The ratio of 
  2598. increase should be as easy to determine as dividing the new clock 
  2599. frequency by 1 MHz for a 64.  If this were true, an accelerator that 
  2600. runs at 4 Mhz would execute things at 4 times the speed of a stock 64.
  2601. Sadly, this is not true, since not all parts of the system can be sped
  2602. up to the higher frequency.  So, the accelerator runs at full speed while
  2603. it utilizes ICs designed for the faster clock speed, and slows down when
  2604. it must "talk" with ICs like the SID and VIC-II in the 64, which run only
  2605. at the slow 1 MHz clock speed.  
  2606.  
  2607. Most accelerators are produced as large cartridges that plug into the
  2608. expansion port of the computer system.  Some require special wires be
  2609. attached to internal components, while others do not.  
  2610.  
  2611. @(A) The New Kid on the Block
  2612.  
  2613. In mid 1995, Creative Micro Designs, after having evaluated the FLASH 8
  2614. accelerator from Europe with only mild success, noted that there might
  2615. possibly be a market for a speedy accelerator that would run GEOS and
  2616. other useful applications in the USA.  After surveying the readership
  2617. of Commodore World, the Internet, and FIDONet, CMD decided that interest
  2618. in such a unit was forthcoming.  Shortly thereafter, the SuperCPU
  2619. announcement was made.
  2620.  
  2621. As development work ensued, progress reports and preliminary information
  2622. about the product surfaced from CMD.  The first items involved the processor
  2623. choice, which was originally the 65C02S but is now its bigger brother, the
  2624. 16 bit 65C816S.  Another piece of information involved the case, which is
  2625. an enclosure 6" wide by 2" deep by 3" wide.  This enclosire contains
  2626. a circuit board protruding from the front of the unit that will plug into
  2627. the Commodore 64 or 128 expansion port.  In back, a complementary card
  2628. edge connector is provided to pass signals through the cartridge.  This
  2629. will allow users to attach other expansion port cartidges to the
  2630. system.  On top sit three switches, described below.
  2631.  
  2632. The first switch enables or disables the SuperCPU unit.  The second switch
  2633. enables or disables JiffyDOS, which is built into the unit.  The third
  2634. switch determines the speed of the unit.  This third switch has three
  2635. positions.  The first position forces the accelerator to operate at 1
  2636. MHz speed (the same speed as the stock C64).  The second position allows
  2637. the programmer to change the speed via a register in the SuperCPU memory
  2638. map.  The third position locks the SuperCPU into 20 MHz mode, regardless
  2639. of register settings.  
  2640.  
  2641. The use of the CMD SuperCPU will be straightforward.  Simply plug the
  2642. unit into the expansion port, set the appropriate switches on the top of
  2643. the unit, and powering on the unit.
  2644.  
  2645. @(A) Technical Details
  2646.  
  2647. The basic system utilizes a WDC W65C816S 16 bit microprocessor running at
  2648. 20 MHz.  This CPU can not only fully emulate a CMOS 6502, it can be
  2649. switched into "native" mode which allows access to 16 bit registers and
  2650. 16 megabytes of RAM without bank switching, DMA, or paging.  See the
  2651. article entitled "Exploiting the 65C816S CPU" elsewhere in this issue
  2652. (Reference: cpu))
  2653.  
  2654. Attached to the CPU is a bank of 64 kilobytes of Read Only Memory (ROM)
  2655. and 128 bilobytes of high speed static RAM (SRAM).  The extra RAM above
  2656. 64 kB is used to "mirror" the contents of the slower ROM.  See below for
  2657. details.
  2658.  
  2659. A number of features designed to maximize the performance of the 
  2660. SuperCPU are being developed into the unit.  Since the late 1980's 
  2661. ROM speeds have not been able to keep pace with CPU clock frequencies.
  2662. With the CMD accelerator moving into the frequency range of newer
  2663. PC systems, this becomes a problem for the SuperCPU as well.  The
  2664. Commodore typically stores its KERNAL and BASIC code in ROMS, and the
  2665. SuperCPU will need to read that code.  The easiest solution is to read
  2666. the stock ROMs in the computer, but those ICs can only be accessed
  2667. at 1 MHz (they are part of that set of older ICs that cannot be utilized
  2668. at 20 MHz).  So, the next option is to copy that code into faster ROMs
  2669. and instal those ROMs int the cartridge.  Well, as stated earlier,
  2670. ROMs of sufficient speed are very expensive and not widely available.  
  2671. So, the third option, which is the one CMD will use, is to copy the
  2672. KERNAL and BASIC at startup to RAM and write protect the RAM area, making
  2673. it look like ROM.  Fast static RAM (SRAM) is available to meet the
  2674. 20 MHz clock requirements, and is not terribly expensive, as most new
  2675. PC systems use the same memory for similar uses.  This technique is
  2676. called ROM shadowing and has been utilized for a few years in the IBM
  2677. PC community.  
  2678.  
  2679. The heart of the unit is the Altera Complex Programmable Logic Device
  2680. (CPLD).  Analogous to electonic "glue", this single chip can replace
  2681. ten or hundreds of discrete ICs in circuits.  This unit is responsible
  2682. for decoding the complex series of signals presented in the expansion
  2683. port, handling DMA requests to an REU unit, emulating the specialize
  2684. I/O port found at locations $00 and $01 on the 6510 CPU, and handling
  2685. the synchronization of the SuperCPU memory and C64 memory.
  2686.  
  2687. One item that has plagued accelerator designers for years and minimized
  2688. the widespread acceptance of accelerators invoves this RAM sync operation
  2689. the Altera CPLD handles.  In areas of the stock C64 memory map where 
  2690. only RAM is present, like $0002 - $40959, the synchronization of
  2691. memory can be handled very easily.  However, when dealing with areas
  2692. like $d000, where RAM AND IO can be present, the situation becomes more
  2693. complex.  The SuperCPU overcomes this problem as well, which is important
  2694. since many video applications use the RAM under IO at $d000 for graphics
  2695. or text.
  2696.  
  2697. As the VIC-II IC in the C64 and C128 requires that screen information be
  2698. present in on-board memory, memory "mirriring" is necessary.  However,
  2699. CMD has introduced two new technologies, called WriteSmart(tm) and
  2700. CacheWrite(tm) to reduce the slowdown associated with mirroring the
  2701. SuperCPU SRAM and the slower on-board DRAM.  According to documentation,
  2702. WriteSmart allows the programmer to decide which portions of memory need
  2703. mirroring.  The four selections include "BASIC", where only text and
  2704. color memory are mirrored, "GEOS", where GEOS foreground bitmap and color
  2705. memory are mirrored, "ALL", where all 64 kB of RAM is mirrored, and 
  2706. "NONE", where the SuperCPU does not attempt to syncronize memory contents
  2707. between the two RAM areas.
  2708.  
  2709. The other technology, called CacheWrite(tm), minimizes the effect of
  2710. this mirroring.  When storing a value into SuperCPU RAM in a range of
  2711. RAM that requires mirroring, the value is stored not only in SuperCPU
  2712. RAM, but also into a special cache memory location.  The SuperCPU is
  2713. allowed to continue processing, while the system waits for the on board
  2714. DRAM to acknowledge readiness to store a value.  When successive stores 
  2715. to mirror ranges are done, the system must slow down, but can still 
  2716. operate at about 4 MHz.  This speed is achieved because the SuperCPU need
  2717. not wait for the value to be successfully stored before it attempts to 
  2718. fetch the next opcode and operand.  Since opcodes that write value to
  2719. memory avarage 4 cycles to complete, the SuperCPU can effectively do 4
  2720. cycles worth of processing in 1 period of the 1 MHz clock.  Note that
  2721. this slowdown does not occur if the cache is not full when a store
  2722. instruction is executed.
  2723.  
  2724. @(A) Features
  2725.  
  2726. Being a CMD product, the CMD SuperCPU comes with JiffyDOS, CMD's
  2727. flagship speed enhancement routines, installed.  However, JiffyDOS
  2728. can be switched out for those applications that fail to run with this
  2729. serial bus enhancement functionality.
  2730.  
  2731. The unit also features compatibility with RAMLink, CMD's RAM drive unit.
  2732. As the RAMLink fucntions by sharing the CPU with the computer system and
  2733. runs a special set of instructions called RL-DOS, the SuperCPU contains its
  2734. own version of RL-DOS optimized to take advantage of the speed and extra
  2735. features available in the 65C816S.  Preliminary information suggests that
  2736. RAMLink data retrieval, typicially much slower the REU data retrieval,
  2737. will now operate at speeds approaching that of the REU.  In addition, the
  2738. on-baord RL-DOS will handle usage of the special parallel CMD HD drive
  2739. cable available with the RAMLink.
  2740.  
  2741. For those with expansion in mind, CMD has incorporated a special
  2742. expansion port internal to the unit.  The port, called the "Rocket
  2743. Socket", will allow access to the complete signal set from the W65C816S
  2744. CPU and possibly other support ICs.  This will allow developers to
  2745. produce peripheral cards for the unit containing hardware that will run 
  2746. at 20 MHz (The cartridge port will still be limited to slow speed).
  2747.  
  2748. @(A): Myths About the Unit
  2749.  
  2750. In the early phases of development, CMD hinted that possibly extra RAM
  2751. installed in the unit could be used as a fast RAM disk, a la RAMLink.
  2752. However, the inability to battery back up that RAM area, coupled with the 
  2753. small increase in speed gained form doing so and the lengthy development
  2754. time needed to realize this feature, has prompted CMD to abandon this 
  2755. idea for the time being.  Later in the development cycle, such an idea
  2756. might resurface, but the feature is most likely never to be implemented.
  2757.  
  2758. Also, early information about the units noted that two speed options would
  2759. be available, but low support for the slower 10 MHz model prompted CMD to
  2760. discontinue development on that version.  As of now, there is only one
  2761. speed option available: 20 MHz.
  2762.  
  2763. When CMD first announced the unit to the public, it was to include the
  2764. Western Design Center W65C02S microprocessor.  However, in late 1995/early
  2765. 1996, CMD opted to switch from that CPU to its bigger brother, the W65C816
  2766. 16 bit CPU, owing to small increase in per item cost, more flexibility, and
  2767. more expansion options.  See the article elsewhere in the issue about 
  2768. the features of the 65C816S. (Reference: cpu))       
  2769.  
  2770. Although the speed of the CPU in the SuperCPU unit is running at 20 MHz,
  2771. that does not imply all operations will occur twenty times faster.  Some
  2772. operations, like reads from I/O ICs, derial bus operation, and mirroring
  2773. of video memory, require the CPU to slow down temporarily.  This will
  2774. reduce the effective speed to about 17-18 MHz.
  2775.  
  2776. @(A): Compatibility Issues
  2777.  
  2778. All legal 6502/6510/8502 opcodes are supported in the accelerator.  
  2779. Undocumented or "illegal" opcodes are not supported and will fail.  
  2780.  
  2781. Although not a compatibility issue, some applications that rely on the
  2782. CPU running at a certain speed to correctly time events will most likely
  2783. fail or operate too quickly to be useful.  Event or interrupt driven
  2784. code should operate correctly.
  2785.  
  2786. The SuperCPU 64 model will operate correctly with any C64 or C64C model
  2787. of computer system, as well as with any C128 or C128D in 64 mode.  However,
  2788. CMD has recently announced a 128 native version of the cartridge.
  2789.  
  2790. @(A): Super128CPU
  2791.        
  2792. In early 1996, CMD announced that interest was compelling and that would 
  2793. begin development on a 128 version of the SuperCPU.  As a result of this
  2794. announcement, the ship date was moved from Februarty to April as CMD 
  2795. validated the SuperCPU design so that it could be used to manufacture 
  2796. both the SuperCPU 64 and SuperCPU 128.  Both units will operate at a 
  2797. maximum of 20 MHz, and will most likely be packaged in the same enclosure.
  2798. The SuperCPU 128 will operate in both 64 mode and native 128 mode.  It
  2799. will not enhance CP/M mode on the C128.  CMD announced that the
  2800. availability of this unit would be Auguest or September ot 1996.  As far
  2801. as cost is concerned, a current estimate falls at $300.00, and advance
  2802. orders are being taken with a security deposit of US$50.00 needed to
  2803. place an advance order.
  2804.  
  2805. As this announcement was made, some confusion has resulted in the naming
  2806. scheme.  Previously called the SuperCPU or SuperCPU 64/20 (64 model at
  2807. 20 MHz), the new models are referred to as alternately:
  2808.  
  2809. 128 model         64 model
  2810.  
  2811. Super128CPU       Super64CPU
  2812. SuperCPU 128/20   SuperCPU 64/20
  2813.  
  2814. @(A) Prototype Testing and Benchmarks
  2815.  
  2816. As no developer unit have shipped as of this date, CMD has the sole unit
  2817. availabel for be testing and benchmarks.  CMD's prototype unit consists
  2818. of a handwired unit on perfboard.  At first, CMD was hesitant that the
  2819. prototype would actually run at 20 MHz, since such designs are not
  2820. "clean" and can suffer from eignal degradation, signal skew, and 
  2821. crosstalk, which inhibits operation at higher frequencies.  So, with
  2822. that in mind, early tests were done at 4 MHz.  CMD reported in late
  2823. Fenbruary 1996 that the prototype had been ramped up to 20 MHz and was
  2824. operating correctly.  In fact, the unit appears to run faster than it
  2825. can, illustrated by the following example:
  2826.  
  2827. CMD tested the following program at 1 MHz on a Commodore 64
  2828.  
  2829. 10 TI$="000000"
  2830. 20 FORI=1TO10000:NEXT
  2831. 30 PRINTTI
  2832.  
  2833. The result from this test was 660.  After enabling the unit, the test was
  2834. rerun and the result printed out again: 31.    
  2835.  
  2836. Quick calculations by the CMD personnel verified that the unit was
  2837. executing this program 21.29 times the normal speed.  However, that
  2838. is impossible, as the CPU is only clocked 20 times the nortmal speed.
  2839.  
  2840. The supposed impossibility is explained if you delve deeper into the
  2841. timing of the 64.  As many know, the VIC-II "steals" cycles from the CPU
  2842. in order to refresh the VIC-II video screen.  Extra cycles are "stolen"
  2843. for sprites.  With the SuoperCPU disabled, the above code runs at 1 MHz
  2844. minus the amount of time the VIC-II "steals" from the CPU.  With the
  2845. SuperCPU enabled, the VIC-II does not "steal" cycles from the unit, as
  2846. the accelerator uses it own private memory area for operation.  The VIC,
  2847. meanwhile, uses the on-board C64 memory.  
  2848.  
  2849. CMD notes that games that use timers or are event driven function
  2850. correctly, but hotse that count processor cycles or utilize spin-wait
  2851. loops run so quickly as to be virtually unusable.
  2852.  
  2853. Of partiular note to Commodore Hacking readers is the test done with the
  2854. object code for the Polygonamy (Reference: polygon) article elsewhere in
  2855. this issue.  On a stock 64, the program renderes approximately 12-13
  2856. frames per second.  With the SuperCPU enabled, the frame rate jumped to 128
  2857. fps.  CMD notes that further gains might be realized if the code was
  2858. modified to cooperate more fully with the CupserCPU memory scheme.
  2859.  
  2860. As for Ram Expansion Unit compatibility, CMD responds that the issues
  2861. have been tackled and that DMA operation is available on the SuperCPU
  2862. unit.  In adiition, CMD notes that the CPU need not be running at 1 MHz
  2863. to initiate a DMA transfer.  
  2864.  
  2865. As stated from the beginning, the 64 model of the SuperCPU accelerator
  2866. wil work on the Commodore 128 in 64 mode, and test have confirmed that
  2867. the prototype 64 model does indeed frunction correctly any the C128 and
  2868. C128D.
  2869.  
  2870. @(A): Conclusion
  2871.  
  2872. While it is too early to determine the success of the CMD SuperCPU 
  2873. product, the company has a reputation for delivering stable products
  2874. packed with features.  While no accelerator can guarantee 100%
  2875. compatibility with all Commodore software, the CMD offering should provide
  2876. the best compatibility options thus far, due to its solutions to
  2877. RAM synchronization problems that have plagued accelerator designers for
  2878. years.  The fact that CMD also owns the marketing rights to the GEOS
  2879. family of software products and manufacturers a wide variety of
  2880. successful mass media storage devices bodes well for compatibility with
  2881. those applications and peripherals.
  2882.  
  2883. @(A): For More Information
  2884.  
  2885. TO find out more about the CMD SuperCPU family of accelerators, contact
  2886. CMD at the following address of via email:
  2887.  
  2888. Creative Micro Designs, Inc.
  2889. P.O. Box 646
  2890. East Longmeadow,  MA  01028-0646
  2891. (413) 525-0023  (Information)
  2892. (800) 638-3263  (Ordering only)
  2893. cmd.sales@the-spa.com  (Internet Contact for Sales)
  2894.  
  2895. Advance orders are being taken for all units, and the cost to place an
  2896. advance order is $50.00.
  2897.  
  2898. For programmers, CMD is planning to make available a Developer's Package,
  2899. which will help those wanting to exploit the potential of the new unit to
  2900. achieve success.  A W65C816S assembler supporting all the new opcodes and
  2901. addressing modes will be provided, as will documentation pertaining to the
  2902. unit, the CPU, and its capabilities.
  2903.  
  2904. =========================================================================
  2905.  
  2906. @(#)surf: Hack Surfing
  2907.   
  2908. For those who can access that great expanse of area called the World Wide
  2909. Web, here is some new places to visit that are of interest to the Commodore
  2910. community.  In early 1994, when the US Commodore WWW Site started, the number
  2911. of sites online that catered to Commodore numbered in the 10's.  Now, the
  2912. number is in the 100's.  What a change.
  2913.  
  2914. If you know of a site that is not listed here, please feel free to send it
  2915. to the magazine.  The following links have been gleaned from those recently
  2916. changed or added to the US Commodore WWW Site Links page 
  2917. (http://www.msen.com/~brain/cbmlinks/).  
  2918.  
  2919. To encourage these sites to strive to continually enhance their creations,
  2920. and because we like to gripe :-), we'll point out an improvements that 
  2921. could be made at each site. 
  2922.  
  2923. @(A): Companies
  2924.  
  2925. o  http://www.armory.com/~spectre/cwi.html
  2926.    Computer Workshops Incorporated.  CWI shows off their newest software
  2927.    offerings on this well-crafted WWW site.  The darkbackground provides
  2928.    for visual effects, and the content is good as well.  At the time we "hit"
  2929.    the page, CWI was working on a new game called Nether for the 64/128.  
  2930.    From the information, it looks like a 3D action adventure.  CWI offers
  2931.    both CBM and MS-DOS titles.  Some are shareware, while others are
  2932.    commercial.  C=Hacking gripe:  We don't mind the MS-DOS information, but 
  2933.    the diehard CBM user should be able to skip it.  As of now, it's all on
  2934.    the same page.
  2935.  
  2936. o  http://www.msen.com/~brain/guest/Gaelyne_Moranec/qwkrr/
  2937.    QWKRR128, by Rod Gasson.  Gaelyne Moranec, a supporter of QWKRR, presents
  2938.    this site for new and advanced users.  The site is devoted to QWKRR128, a
  2939.    QWK-based offline mail reading program for BBS and Internet use, and 
  2940.    Browser, a utility for reading large files on the 64/128.  The site
  2941.    is clean and simple, with no fancy graphics, but lots of meaty information.
  2942.    Links include the QWKRR128 user's manual, the actual product's binaries,
  2943.    and helper applications needed to use QWKRR128.  C=H gripe: It's hard to
  2944.    tell what all I need to read Internet email via QWKRR128.  
  2945.  
  2946. o  http://www.msen.com/~brain/guest/rms/
  2947.    RMS Computer Systems.  RMS offers up its line of services from this site,
  2948.    including software distribution, parts and accessories, and consulting/
  2949.    training.  RMS can even design your WWW pages.  The pages are colorful
  2950.    and clean, using either Microsoft Explorer or Netscape Navigator
  2951.    extension depending on the browser chosen off the home page.  RMS offers 
  2952.    the C-Net BBS software for sale and present information on the 64 and
  2953.    128 versions of the program.  C=H gripe:  The home page offers a choice
  2954.    of using Netscape of Microsoft Explorer.  What about the Lynx text mode
  2955.    browser?  Which do they pick?
  2956.  
  2957. @(A): Publications
  2958.    
  2959. o  http://www.the-spa.com/cmd/cwhome.html
  2960.    Commodore World.  CMD's publications is presented at this site, with 
  2961.    select articles, and information for potential writers and subscribers
  2962.    is detailed.  The site is laid out well and provides for easy reading.
  2963.    Of course, we're not sure it does justice to the magazine, but that's 
  2964.    true of LOADSTAR's home page as well.  C=H gripe: the site needs updating,
  2965.    as the change dates are 9-95.  When they do update it, we hope they'll
  2966.    remove that annoying "blink" tag!
  2967.    
  2968. @(A): User's Groups
  2969.  
  2970. o  http://www.ccn.cs.dal.ca/Technology/CUGNS/CBM.html
  2971.    Cnada Commodore Users Group of Nova Scotia.  The site makes use of
  2972.    color and grpahics to provide links to a number of Commodore content
  2973.    sites on the Internet.  It links up with other user groups on the 'Net,
  2974.    and provides a public download area for software retrieval. C=H gripe:
  2975.    We still think this is a user's group, but no meetings, minutes, 
  2976.    newsletters, or times and dates were mentioned.  Whare are they?
  2977.    
  2978. o  http://www.fastlane.net/homepages/msessums/64.html
  2979.    Metro C-64/128 User's Group.  Meeting dates, times, agendas, and some
  2980.    general information are provided on this page.  You can also learn about
  2981.    this groups parent organization, the Metroplex Commodore Computer Club.  
  2982.    C=H gripe: some newsletters from past meetings and a bit more about the 
  2983.    group would be nice.
  2984.    
  2985. o  http://www.inna.net/mpcug/mpcug.html
  2986.    The Middle Peninsula Computer Users Group.  Go here to find out just
  2987.    WHY the groups is named this way.  Meeting times, dates, places, past
  2988.    newsletter articles, and background information is provided.  The site
  2989.    has a sprinkle of color and graphcis to break up the text.  C=H gripe:
  2990.    It looks like the group is multi-platform, but no mention is made of
  2991.    what Commodore 8-bit owners will find at meetings.  Maybe we missed it.
  2992.    
  2993. @(A): Demo Groups
  2994.  
  2995. o  http://rphc1.physik.uni-regensburg.de/~pem03049/eqx/
  2996.    The EQUINOXE WWW Site.  This demo group puts on a good show, with
  2997.    content and color on their WWW site.  Here is where you can find 
  2998.    the announcement on the upcoming Shout! #2 magazine release.  The list
  2999.    of links is implressive as well.  C=H gripe:  The front page use of large
  3000.    fonts sizes is a bit overdone.
  3001.    
  3002. o  http://flash.lakeheadu.ca/~jgvotour/index.html
  3003.    The OMNI/Revenge WWW Site.  Color and content are mixed well on this 
  3004.    site as well.  A bit of history about Revenge is given, links to the
  3005.    demos to download is present, and information about upcoming releases
  3006.    is detailed.  C=H gripe: We'd like to know more about the person behind
  3007.    the well-done page.  
  3008.  
  3009. @(A): Miscellaneous
  3010.  
  3011. o  http://vanbc.wimsey.com/~danf/cbm/languages.html
  3012.    Dan Fandrich's Commodore Languages List.  Extensive doesn't really
  3013.    describe this page, which provides information on assemblers, compilers,
  3014.    cross-compilers, and interpreters for many different programming
  3015.    langauges supported by the Commodore 8-bit.  Rare items like language
  3016.    support for the 264 series and the SuperPET are described as well. 
  3017.    C=H gripe:  the page is HUGE.  Any chance of a breakdown into spearate
  3018.    files?
  3019.  
  3020. o  http://rrnet.com/~bfrandse/viccarts.html
  3021.    The Commodore VIC-20 Cartridge List.  Cartridges from many different
  3022.    software companies are detailed, and both games and utilities are listed.
  3023.    As with the Programming Language Page, this list is extensive.  It notes
  3024.    in the opening credits the trasnsitions the list has made to arrive at
  3025.    this current form.  C=H gripe: same as for the langauge list.  This thing
  3026.    is LARGE, and might benefit from a more heirachial listing treatment.
  3027.  
  3028. o  http://fox.nstn.ca/~ptiwana/john/webpage1.html
  3029.    John Elliot's WWW Site.  This page explores the use of Commodore computers
  3030.    and other "orphan" machines to better education by improving the student/
  3031.    computer ratio.  The information presented in this site is heartwarming,
  3032.    as it shows practical uses to dispel the myth that 8-bits are truly
  3033.    useless.  C=H gripe: Not really a gripe, but we sure would like to see more
  3034.    of these reall world examples.
  3035.  
  3036. o  http://www.ksk.sala.se/~sp93rob/dungeon/
  3037.    The Alternate Reality WWW Site.  For those wanting to relive the best of
  3038.    this game for the 64, visit this site.  Everything from tips to tricks,
  3039.    stories to confidential material, and screenshots are available at this
  3040.    site.  C=H gripe:  The color scheme is a bit rough on the eyes, but it
  3041.    does look neat.
  3042.  
  3043. o  http://www.lysator.liu.se/tolkien-games/c64.html
  3044.    Fredrik Ekman's Tolkien Games WWW Site.  The name says it all.  If
  3045.    you've ever played a Tolkien game, here is where they are listed and
  3046.    examined.  Fredrik give the history of each game, the solutions if there are
  3047.    any, and describes the game itself.  C=H gripe:  We left impressed with the
  3048.    information but wondering why someone would go to this effort.  Tell us, 
  3049.    Fredrik.
  3050.  
  3051. o  http://ubmail.ubalt.edu/~telliott/commodore.html
  3052.    Todd Elliott's Commodore 64/128 WWW Site. Todd provides some commentary
  3053.    and links to hardware hacks and ML tips.  Of particular interst is his
  3054.    introduction to the Commodore C64 and C128 computers, which explains
  3055.    some of the history behind the machines.  Our favorite passage in this
  3056.    page details his experisnces with Radio Shack.... C=H gripe:  We'd like 
  3057.    to know how Todd Elliott fits into the Commodore 8-bit arena.
  3058.    
  3059. @(A): Change of Address
  3060.  
  3061. o  CMD recently moved to http://www.the-spa.com/cmd/
  3062.    CMD heard our issue #11 gripe, as the home page now has links directly
  3063.    to the SuperCPU information.
  3064.  
  3065. o  LOADSTAR has moved to http://www.softdisk.com/comp/loadstar/
  3066.  
  3067. o  Marc-Jano Knopp's CBM WWW Site is at:
  3068.    http://www.student.informatik.th-darmstadt.de/~supermjk/c64.html
  3069.  
  3070. o  The US Commodore WWW Links Site has moved to:
  3071.    http://www.msen.com/~brain/cbmlinks/
  3072.  
  3073. ============================================================================
  3074.  
  3075. @(#)trivia: Commodore Trivia
  3076.             by Jim Brain (brain@mail.msen.com)
  3077.           
  3078. @(A): Introduction
  3079.  
  3080. I had the good fortune of receiving some fine back issue of magazine and
  3081. old books from a friend in Michigan (thanks Gaelyne), so I got busy reading
  3082. and gleaning.  The result is a new crop of trivia questions guaranteed to
  3083. rack your brain and have you reachin' for those numerous Commodore
  3084. publications.  Go ahead, I won't mind.  
  3085.  
  3086. As some may know, these questions are part of a contest held each month on
  3087. the Internet, in which the winner receives a donated prize.  I encourage
  3088. those who can received the newest editions of trivia to enter the contest.
  3089.  
  3090. This article contains the questions and answers for trivia editions #23-26,
  3091. with questions for the current contest, #27.
  3092.  
  3093. If you wish, you can subscribe to the trivia mailing list and receive the
  3094. newest editions of the trivia via Internet email.  To add your name to the
  3095. list, please mail a message:
  3096.    
  3097. To: brain@mail.msen.com
  3098. Subject: MAILSERV
  3099. Body:
  3100. subscribe trivia Firstname Lastname
  3101. help
  3102. quit
  3103.    
  3104. @(#): Trivia Questions
  3105.  
  3106.         A publication describing BASIC on the Commodore makes the claim that
  3107.         BASIC variables are limited to 5 characters, with the first two being
  3108.         significant.  The example to prove this point in the book is given as:
  3109.  
  3110.         ABCDE=5   works, while
  3111.         ABCDEF=6  does not.
  3112.  
  3113.         The following questions refer to this claim:
  3114.  
  3115. Q $160) What is wrong with the above statement?
  3116.  
  3117. A $160) Variables can indeed be longer than 5 characters.
  3118.  
  3119. Q $161) What causes the variable ABCDEF to fail?
  3120.  
  3121. A $161) The variable name fails becase the BASIC keyword "DEF" in it.
  3122.  
  3123. Q $162) How long can variable names really be?
  3124.  
  3125.         Extra Credit:  Who was the book publisher?
  3126.  
  3127. A $162) As long as the maximum command line length.  Theoretically, using
  3128.         automated code generation, you can get a variable name that is
  3129.         just shy of 255 characters in length.
  3130.         
  3131.         Oh, and Abacus wrote the offending book.
  3132.  
  3133.         The Commodore LCD Computer system, much like the Commodore 65,
  3134.         was a product that never reached the market.  Do you remember this
  3135.         pint-size CBM machine?
  3136.  
  3137. Q $163) How many keys were on the CLCD keyboard?
  3138.  
  3139. A $163) 72 keys, including 8 function keys and 4 separate cursor keys.
  3140.  
  3141. Q $164) What does LCD in the Commodore LCD stand for?
  3142.  
  3143. A $164) Liquid Crystal Display.
  3144.  
  3145. Q $165) Was an internal modem to be includes?
  3146.  
  3147. A $165) Yep, A 300 bps auto dial/auto answer modem.
  3148.  
  3149. Q $166) Like the Plus/4 the CLCD unit had integrated software.  What programs
  3150.         were included?
  3151.  
  3152. A $166) As referenced in $158, there are 8 integrated programs:
  3153.  
  3154.         Word Processor
  3155.         File Manager
  3156.         Spreadsheet
  3157.         Address Book
  3158.         Scheduler
  3159.         Calculator
  3160.         Memo Pad
  3161.         Telecommunications Package
  3162.  
  3163. Q $167) How many batteries of what type did the CLCD use for power?
  3164.  
  3165. A $167) 4 AA alkaline batteries.
  3166.  
  3167. Q $168) Approximately how much did the CLCD unit weigh?
  3168.  
  3169. A $168) 5 pounds.
  3170.  
  3171. Q $169) What version of BASIC was to be included with the CLCD computer?
  3172.  
  3173. A $169) 3.6.  It contained all of Basic 3.5 plus a few extras.
  3174.  
  3175. Q $16A) The CLCD unit contained a port that could be used with a 
  3176.         Hewlett-Packard device.  What did the device do?
  3177.  
  3178. A $16A) An HP bar code reader.  
  3179.  
  3180. Q $16B) What microprocessor did the CLCD unit utilize?
  3181.  
  3182. A $16B) The 65C102 CPU.  This CPU was built using the 65C02 core from
  3183.         Western Design Center, who licenses the popular 65C816S CPU
  3184.         as well.  CBM licensed this chip at little or no cost as a result 
  3185.         of a lawsuit settlement between WDC and CBM over 6502 architecture
  3186.         patent infringements.
  3187.  
  3188. Q $16C) In addition to the usual inclusion of standard Commodore ports,
  3189.         what two industry standard ports were included on the CLCD?
  3190.  
  3191. A $16C) Centronics Parallel (printer) port, and an EIA-232 (RS-232C) port.
  3192.  
  3193. Q $16D) How much RAM did the CLCD computer include?
  3194.  
  3195. A $16D) 32kB of battery backed RAM.
  3196.  
  3197. Q $16E) How many pixels are on the LCD screen on the CLCD machine?
  3198.  
  3199. A $16E) 480 x 128 or 61440 pixels
  3200.  
  3201. Q $16F) How much ROM did the CLCD computer contain?
  3202.  
  3203. A $16F) 96kB of ROM, which held the OS and the integrated programs.
  3204.  
  3205. Q $170) What text is displayed on the screen of a Commodore 128 upon
  3206.         bootup?
  3207.  
  3208. A $170) The following text is centered on either the 40 or 80 column
  3209.         screen:
  3210.  
  3211.         COMMODORE BASIC V7.0 122365 BYTES FREE
  3212.           (C)1985 COMMODORE ELECTRONICS, LTD.
  3213.                 (C)1977 MICROSOFT CORP.
  3214.                   ALL RIGHTS RESERVED
  3215.  
  3216. Q $171) How many bytes free does a Commodore 128 have on powerup?
  3217.  
  3218. A $171) As shown above in Q $170, 122365 bytes.
  3219.  
  3220. Q $172) On the Commodore B-128 series, the bell beeps at the right margin.
  3221.         What column is the default right margin on the B-128?
  3222.  
  3223. A $172) Column 70.
  3224.  
  3225. Q $173) When a Commodore C64 is hooked up to a 1541 and an MPS 801
  3226.         printer, everything is powered up and connected correctly, and
  3227.         the floppy won't load.  What is wrong?
  3228.  
  3229. A $173) The printer is offline.  Put the printer on-line, and the floppy
  3230.         will operate correctly.
  3231.  
  3232. Q $174) How do you access the "hidden message" in the C128DCR?
  3233.  
  3234. A $174) One brute force way:
  3235.  
  3236.         While in the machine language monitor, type:
  3237.        
  3238.           m f63f5 f640b
  3239.  
  3240. Q $175) Some of you may remember the Commodore Magic Voice cartridge.
  3241.         If so, how many words was in the base unit's vocabulary?
  3242.  
  3243. A $175) 235
  3244.  
  3245. Q $176) Who write the 3+1 software bundled with the Commodore
  3246.         Plus/4 in ROM.
  3247.         
  3248. A $176) Tri Micro wrote the code, and created a version for the C64.
  3249.         It turns out that the 3+1 software included with the Commodore
  3250.         Plus/4 was originally designed to be but one of the many choices
  3251.         for bundled software with the 264.  When the focus changed, 3+1
  3252.         became the only software bundled, and some assumed Commodore
  3253.         had written it.  (Ref. RUN April 1985:43)
  3254.  
  3255. Q $177) The BASIC extension "Simon's BASIC" was created by whom?
  3256.  
  3257. A $177) David Simons (Ref: Commodore Power/Play April/May 1985:56-7)
  3258.  
  3259. Q $178) Simons' BASIC was influenced a lot by what other computer
  3260.         manufacturer's BASIC?
  3261.  
  3262. A $178) Hewlett Packard.  (Commodore Power/Play April/May 1985:56)
  3263.  
  3264. Q $179) How many commands does Simons' BASIC add to the Commodore 64?
  3265.  
  3266. A $179) 114. (P/P Apr/May 1985:57)
  3267.  
  3268. Q $17A) In the United Kingdom, there was an extension to Simons' BASIC
  3269.         developed by David.  Among other things, what major complaint
  3270.         about the original BASIC extension does it address?
  3271.  
  3272. A $17A) Renumbering GOTOs and GOSUBs when renumbering a program.
  3273.  
  3274. Q $17B) In the Commodore Plus/4 File Manager, there exists two bugs, 
  3275.         which show up if you have over a certain number of records.  What
  3276.         is this magic number?
  3277.  
  3278. A $17B) When merging over 255 records in the Word Processor, a printout might
  3279.         stop early int the file and continually reprint a single record, or
  3280.         entering one record might trash another record. (RUN April 1985:43)
  3281.  
  3282. Q $17C) Commodore Semiconductor Group (CSG) manufactured an 8500 IC.
  3283.         What common IC number is this IC functionally equivalent to?
  3284.  
  3285. A $17C) The 6502.  The change in number owes more to a change in 
  3286.         manufacturing process than anything else.
  3287.  
  3288. Q $17D) How many BASIC commands were included in BASIC 3.5, not
  3289.         including the monitor commands?
  3290.  
  3291. A $17D) 80. (RUN November 1984:37)
  3292.  
  3293. Q $17E) On the Commodore VIC-20, 64, and C16 keyboards, what row and
  3294.         column pins on the keyboard connector does the letter D
  3295.         correspond to?
  3296.  
  3297. A $17E) Row 2 Column 2. (RUN July 1984:109)
  3298.  
  3299. Q $17F) What is special about the keys in Row 4 of the hardware keyboard
  3300.         matrix?
  3301.  
  3302. A $17F) Column 2-4 spell out CBM. (RUN July 84:109)
  3303.  
  3304. Q $180) Most people know what CPU is in a Commodore disk drive, but what
  3305.         CPU powers the venerable CBM 1525 printer?
  3306.  
  3307. A $180) You had better sit down.... The 1525 is powered by an Intel 8039
  3308.         8-bit microcontroller.  Actually, this isn't so hard to believe, 
  3309.         since Commodore didn't actually develop the printer, but used a
  3310.         Seikosha GP-100 printer mechanism for the unit, and most likely
  3311.         contracted Seikosha to develop the firmware.
  3312.  
  3313. Q $181) What is the maximum number of characters per line on a CBM 1520?
  3314.  
  3315. A $181) 80.  22 columns per inch times 3.63... inches of usable paper width.
  3316.  
  3317. Q $182) Commodore rarely manufactured its own printer mechanisms.  Who's
  3318.         mechanism did Commodore use in the DPS 1101?
  3319.  
  3320. A $182) The Juki 6100 printer mechanism.
  3321.  
  3322. Q $183) What is unique about the DPS 1101 printer?
  3323.  
  3324. A $183) It is daisy-wheel, but Commodore made other daisy-wheel printers. what
  3325.         makes it unique is that it is the only such serial daisy-wheel made 
  3326.         for the Commodore line.
  3327.  
  3328. Q $184) Which was the first Commodore modem with DTMF dialling capabilities?
  3329.  
  3330. A $184) The first to offer some kind of DTMF support was the Commodore 1660
  3331.         modem.  The modem itself didn't provide any DTMF support, but included
  3332.         a cable to allow the SID to output to the phone line.  Thus, with the
  3333.         SID's ability to reproduce DTMF tones, the modem could tone dial. 
  3334.         Note that this was only possible on the C64, which has a SID.  The
  3335.         first mode to INCORPORATE DTMF into the modem itself was the 1670.
  3336.  
  3337. Q $185) Which was the last Commodore 8-bit peripheral drive developed?
  3338.  
  3339. A $185) By develop, we are referring to actually produced models.  With that
  3340.         definition, the 1581 holds this title.  For models not actually
  3341.         produced, The prototype 1590-D-1 3.5" 1.44 MB model owned by Jack
  3342.         Vander White probably was the last under development.
  3343.  
  3344. Q $186) What is the maximum size of RAM available for use for program
  3345.         storage on an expanded VIC-20
  3346.  
  3347. A $186) 3583 bytes are available for BASIC programs and their variables.
  3348.  
  3349. Q $187) One of the most poular magazines for computers in the 1980's was
  3350.         COMPUTE!  What Commodore content magazine did it give birth to?
  3351.  
  3352. A $187) COMPUTE!'s Gazette. 
  3353.  
  3354. Q $188) In a strange twist of irony, COMPUTE! was itself descended from a
  3355.         Commodore content magazine.  Which one?
  3356.  
  3357. A $188) The PET Gazette.  The PET Gazette was started in April 1978 by Len
  3358.         Lindsey.  For the first year, the magazine was sent out for free to
  3359.         at times 4000 people.  In August of 1979, Small Systems Services, 
  3360.         headed by Robert Lock, purchased the magazine from Len and changed
  3361.         the name to COMPUTE.  The focus changed from PETs to all computer
  3362.         systems at that time.  The first issue of COMPUTE. appeared in the
  3363.         Fall of 1979.  It seems the relationship between Len Lindsay and 
  3364.         Robert Lock was less than ideal, but I refer readers to INFO #15,
  3365.         page 8 for the scoop.
  3366.  
  3367. Q $189) COMPUTE! underwent a name change very shortly after introduction.
  3368.         What subtle change was made to the name?
  3369.  
  3370. A $189) COMPUTE. changed to COMPUTE!  Notice the change?
  3371.  
  3372. Q $18A) How were LOADSTAR and Commodore Microcomputing-Power/Play once
  3373.         connected?
  3374.  
  3375. A $18A) In the mid 1980's, LOADSTAR distributed the type in programs for
  3376.         both magazines in the disk magazine.
  3377.  
  3378. Q $18B) What is the fastest Commodore ever clocked a 6502 or derivative
  3379.         CPU in a machine?
  3380.  
  3381. A $18B) The CSG65CE02 CPU, clocked at up to 3.54 MHz in the Commodore 65
  3382.         (64DX) prototype. 
  3383.  
  3384. Q $18C) Name one byte that yields the same character when printed and poked
  3385.         to a Commodore screen.
  3386.  
  3387. A $18C) Any byte between 32 and 63 will produce identical results.
  3388.  
  3389. Q $18D) Quick, which chr$ value flips to uppercase/lowercase mode?
  3390.  
  3391. A $18D) chr$(14)
  3392.  
  3393. Q $18E) Quicker, which chr$ value flips it back to uppercase/graphics?
  3394.  
  3395. A $18E) chr$(142)
  3396.  
  3397. Q $18F) How do you get INPUT to not display a question mark?
  3398.  
  3399. A $18F) open 1,0:input#0,a$
  3400.  
  3401. Q $190) In reference to Commodore, what does TOI stand for?
  3402.  
  3403. A $190) The Other Intellect.  Evidently, it was the computer the CBM
  3404.         engineers were working on before the VIC-20 project.  The name
  3405.         sounds like it was dreamed up after the fact.  In either case, this 
  3406.         machine might have been the "Color PET" mention in _The Home
  3407.         Computer Wars_ that Chuck Peddle was designing before company 
  3408.         shifted to the VIC architecture.
  3409.  
  3410. Q $191) Name two values that, when poked to the screen, will yield the
  3411.         identical character appearance.
  3412.  
  3413. A $191) 32 and 96 or 160 and 224.  Space and reverse space.
  3414.         103 and 106 or 101 and 116.  Left and right lines.
  3415.      
  3416. Q $192) What chr$ codes lock out and re enable the shift/commodore keyboard
  3417.         flip from uppercase to lowercase on the VIC-20?
  3418.  
  3419. A $192) chr$(8) and chr$(9), respectively.
  3420.      
  3421. Q $193) What chr$ codes lock out and re enable the shift/commodore keyboard
  3422.         flip from uppercase to lowercase on the C64?
  3423.  
  3424. A $193) chr$(8) and chr$(9), respectively.
  3425.      
  3426. Q $194) What chr$ codes lock out and re enable the shift/commodore keyboard
  3427.         flip from uppercase to lowercase on the C128?
  3428.  
  3429. A $194) chr$(11) and chr$(12), respectively, while in 128 mode.
  3430.      
  3431. Q $195) On CBM machines prior to the VIC-20, what chr$ code outputs the
  3432.         same character as chr$(44), the comma.
  3433.  
  3434. A $195) 108.
  3435.      
  3436. Q $196) Is the character described in $195 of any use?
  3437.  
  3438. A $196) To put commas in strings read via INPUT.  Remember, INPUT treats
  3439.         a comma (chr$(44)) as a delimiter between input fields, but chr$(108)
  3440.         does not produce the same effect, so you could replace 44 with 108 in
  3441.         data written to disk, and read it in with INPUT.
  3442.  
  3443. Q $197) The speed of Commmodore BASIC increased dramatically after the first
  3444.         OS upgrade in 1979.  Why?
  3445.  
  3446. A $197) Jim Butterfield supplies us the answer:
  3447.  
  3448.            "The original PET 2001 suffered from the same kind of "screen 
  3449.            sparkle" that was later seen in the early Commodore 64.  So 
  3450.            the original code would write to screen memory only during 
  3451.            the "refresh" period; that really slowed down the speed of 
  3452.            output to the screen.  By the time the first revised PET came 
  3453.            out, the screen sparkle was solved, and characters were 
  3454.            delivered to the screen with no wait. (The new operating 
  3455.            system also did a massive relocation of system variables, 
  3456.            and used zero page very heavily, to the dismay of home 
  3457.            programmers.  When asked about this, Commodore pointed 
  3458.            proudly at the "new, higher speed".  But in fact it was 
  3459.            the screen reorganization that caused 95% of the 
  3460.            improvement)."
  3461.                                           --Jim
  3462.         
  3463.         Related to this question is $00C, which implies that the
  3464.         "sparkle" problem was fixed in the original PETs, so some people
  3465.         increased the performance of the original PET by setting the RETRACE
  3466.         line mentioned above to an output, which fooled the system into 
  3467.         thinking the video was ALWAYS in RETRACE mode.  
  3468.  
  3469. Q $198) COMAL, a programming language available for Commodore computers, was
  3470.         created by whom?
  3471.  
  3472. A $198) Borge Christensen and Benedict Lofstedt, although Borge is given
  3473.         the most credit.
  3474.      
  3475. Q $199) At the 1980 COMDEX, Commodore PETs proved instrumental during a
  3476.         crisis.  What happened?
  3477.  
  3478. A $199) The following is excerpted from _The Whole PET Catalog_, page 21:
  3479.  
  3480.            "PET PROVEN USEFUL"  During the 1980 MGM Grand fire in Las 
  3481.            Vegas, Commodore moved its entire COMDEX '80 booth dowstairs 
  3482.            to help track rooms, guests, etc.  According to _InfoWorld_, 
  3483.            7 PETs with OZZ data-bases (predecessor to SILICON OFFICE)
  3484.            were used for two straight days.  Local police agreed they
  3485.            could not have kept of the guests as well as the PETs did.
  3486.            Also, untrained operators quickly learned the system.  In the
  3487.            crisis, PET was both powerful and useable.
  3488.  
  3489. Q $19A) Who designed the PET/CBM 8032 computer?
  3490.  
  3491. A $19A) Bill Seiler, the able assistant to Chuck Peddle, designed the unit.
  3492.      
  3493. Q $19B) What was the "cursor gone out to lunch" bug in the first PETs?
  3494.  
  3495. A $19B) No answer available yet (I can't find my notes!)
  3496.      
  3497. Q $19C) On a PET/CBM (early models), what will "POKE 14,1" do?
  3498.  
  3499. A $19C) If done immediately prior to an INPUT, the poke will suppress the
  3500.         question mark prompt.
  3501.  
  3502. Q $19D) What version of BASIC would not utilize disk drives?
  3503.     
  3504. A $19D) BASIC 1.0
  3505.      
  3506. Q $19E) Who is Lyman Duggan and why is he important?
  3507.  
  3508. A $19E) He is one of the founding fathers of the Toronto PET User's Group
  3509.         (TPUG), along with Jim Butterfield.
  3510.  
  3511. Q $19F) Jim Butterfield notes to me that he received plenty of help in
  3512.         creating the first PET memory map (Q $0D8) from the Sphinx group,
  3513.         who published critical information in their early newsletters.  How
  3514.         did Commodore influence the name of the group?
  3515.  
  3516. A $19F) The name "Sphinx" was chosen because of the way early PETs resembled
  3517.         the Great Sphinx, the Lion with the head of a pharoah.
  3518.  
  3519. Q $1A0) Commodore produced an assembler for the 128 called HCD65.  What
  3520.         does HCD stand for?
  3521.  
  3522. Q $1A1) Who wrote most of RAM DOS?
  3523.  
  3524. Q $1A2) What is the name of the first C64 disk copy program?  (hint: it
  3525.         sported a "gas gauge".)
  3526.  
  3527. Q $1A3) What was the case color of the original Commodore 64s?
  3528.  
  3529. Q $1A4) There are at least two ways to enter 64 mode from 128 mode on a C128:
  3530.         go 64 and sys 65357.  They produce the same result (64 mode), but
  3531.         they differ in at least one noticable way.  How?
  3532.  
  3533. Q $1A5) What CPU powers the B-128 computer system?
  3534.  
  3535. Q $1A6) What type of drive mechanisms are in the D series hard drives from
  3536.         Commodore? 
  3537.  
  3538. Q $1A7) Commodore produced a 16kB RAM expander for the Commodore VIC-20.
  3539.         What is its model number?
  3540.  
  3541. Q $1A8) Commodore produced at least one disk drive with an optical track
  3542.         one sensor.  Which drive?
  3543.  
  3544. Q $1A9) The Commodore PET series used the IEEE bus to communicate with
  3545.         peripherals.  Each peripheral had a unique ID.  What range of IDs
  3546.         are supported by the PET?
  3547.  
  3548. Q $1AA) Many people have developed Commodore software with the PAL assembler.
  3549.         What does PAL stand for?
  3550.  
  3551. Q $1AB) Many people remember Compute's Gazette.  This magazine is best known
  3552.         for the word processor program it shared with thousands of
  3553.         subscribers.  Name the program?
  3554.  
  3555. Q $1AC) In some 6502 assemblers, the opcode "bge" is available.  It stands 
  3556.         for "branch if greater than or equal to".  What more common opcode 
  3557.         is this opcode referring to?
  3558.  
  3559. Q $1AD) If I wanted to do a "blt" (branch if result less than), what 6502 
  3560.         opcode would i use?
  3561.  
  3562. Q $1AE) Each Commodore peripheral has a device number, which is associated
  3563.         with a type of device.  8-15 implied disk drive, 4-5 implies
  3564.         printer.  These have remained constant from the PET to the C128.
  3565.         However, one peripheral in the PET was phased out and its device
  3566.         number was reused.  What device number was reused?
  3567.  
  3568. Q $1AF) What is the maximum amount of general purpose RAM can one utilize
  3569.         in a stock C64?  (I need an exact number here)
  3570.  
  3571. =========================================================================
  3572.  
  3573. @(#)gfx: Talking to TED: The MOS 7360/8360 Text Display ICs
  3574.          by Harsfalvi Levente (TLC@MSZI.PMMF.HU)
  3575.  
  3576. @(A): Introduction
  3577.  
  3578. This information file is based on my old books, descriptions, and especially
  3579. my experiences while I was coding.  That's no mistake.  The Plus/4 series
  3580. was not very famous in the world, but they were very poular in mideast
  3581. Europe.  In fact, there were even demo groups for the machine.  I learned
  3582. some of this information while writing demos for the machine in demo groups,
  3583. while other things were gleaned from personal work on the machine.  These
  3584. computers did indeed play an important part in Commodore computer history.
  3585.  
  3586. I started my first code development on a Plus/4 in late 1986.  After I saw a
  3587. HomeLab 3 (made in Hungary, U880 - GDR made Z80 compatible proc, B/W, 16K),
  3588. I started writing demos and other software for the Plus/4 machine I owned. 
  3589. It actually wasn't that strange to see demo groups sprout up for all 
  3590. kinds of machines, including the Plus/4.  All over, there were groups
  3591. and individuals, writing software while trying to keep the flame lit for
  3592. each machine.  In fact, I know people currently working in groups writing
  3593. for the Plus/4 in Hungary, Germany, and as far away as Alaska.
  3594.  
  3595. @(A): Overview
  3596.  
  3597. Let's discuss the TExt Editor (TED) IC and its environment. This DIL-48 IC
  3598. was designed specifically for the 264 series of machines, which initially
  3599. included the CV364 and the 264, evolving into the Plus/4, C16, and C116 
  3600. machines.  Unlike the CIA or ACIA or other machines, this IC isn't well 
  3601. suited to any other system.
  3602.         
  3603. The TED contains all functions done by several chips in former Commodore 
  3604. computers. The TED is a complete video-interface and composite video
  3605. signal generator, sound generator, keyboard input latch, timer, 
  3606. clock generator, memory manager and DRAM refresher in a single IC.  It can
  3607. address the full memory map of the 264 series machines, and it generates
  3608. the RAS', CAS', and MUX signals for the DRAM memory used in that series.
  3609. For ROM, it generates the chip select (CS) lines, depending on the state
  3610. of the internal registers.  So, in addition to all the above duties, the
  3611. TED IC is a simplistic MMU as well.
  3612.  
  3613. @(A): Video Information
  3614.  
  3615. We see the TED chip shine as it does its primary job, displaying graphics.
  3616. Its abilities mostly parallel those of the uniquitous VIC-II video IC in the
  3617. C64.  It has the following modes:
  3618.  
  3619. *  40x25 screen (characters)
  3620. *  enhanced color mode
  3621. *  multicolor mode
  3622. *  320x200 Hi-Res Graphics
  3623. *  160x200 Multicolor Graphics
  3624.  
  3625. Of course, there are differences.  TED does not contain sprite support.
  3626.  
  3627. To offset this omission, the TED chip can select 8 intensities for each of
  3628. the 16 supported colors, giving 121 colors (the 8 shades of black are all
  3629. black).  Other features include a hardware cursor, hardware text blinking,
  3630. and hardware inverse character support.  Character sets, screen and color
  3631. memory, and graphics bitplanes can be addressed directly, without additional
  3632. logic as found on the C64.  In fact, even RAM/ROM selection requires change
  3633. of a single bit.
  3634.  
  3635. Character modes need $800 bytes of RAM for screen and color memory. The
  3636. first $400 bytes act as color memory (the memory permanently located at 
  3637. $d800 on the C64), with the lower 4 bits containing color codes, exactly
  3638. as found on the 64.  Bits 4-6 denote the intensity level of the color, while
  3639. the high bit select flashing/no-flashing attributes. The other $400 bytes 
  3640. contain the screen codes for the displayed characters.  If hardware
  3641. character inversion is selected, the lower 7 bits hold the screen code and
  3642. the high bit selects inversion for the character.  If character inversion
  3643. is not selected, all 8 bits denote the screen code. Extended Color Mode (ECM)
  3644. and Multi Color Mode (MCM) modes work exactly as described on the 64.  While
  3645. these two modes are in effect, inversion and blinking are disabled.  
  3646.  
  3647. Things get a bit more complex in graphics mode (pun unintentional).  In
  3648. graphcis mode, the bitplane occupies $2000 bytes and is handled just like a
  3649. VIC-II biplane.  The colors are handled differently.  $800 bytes are needed
  3650. for color memory, which is laid out in $400 bytes of intensity memory
  3651. and $400 bytes of color memory.  An "off" bit in the bitplane uses the 
  3652. lowest nybble of the appropriate color memory location as the color and
  3653. retreieves the intensity from bits 4-6 of the appropriate intensity memory
  3654. location.  For an "on" bit, the color is taken from the high nybble of the
  3655. appropriate color memory location, while the intensity is taken from bits 
  3656. 0-2 of the intensity memory location.  Bits 3 and 7 in intensity memory are
  3657. unused.
  3658.  
  3659. In multicolor mode, differences abound.  The 64's VIC-II enabled one to 
  3660. utilize 3 different colors in each 8x8 cell and a single background.  The
  3661. TED simply cannot accomplish this due to the lack of adequate color memory.
  3662. So, TED allows only 2 varying colors per 8x8 cell. Those colors are chosen
  3663. from the palette of 121.  The remaining 2 colors are chosen for the
  3664. entire screen, again from the 121 color palette.  The mapping is as 
  3665. follows:
  3666.  
  3667.    00   background color
  3668.    01   same as "off" color in hires mode
  3669.    10   same as "on" color in hires mode
  3670.    11   another "background" color
  3671.    
  3672. The TED IC is able to generate both PAL and NTSC compatible signals from
  3673. a single IC.  Only the crystal need be changed to go from one standard to
  3674. the other.  In PAL mode, there are 312 lines hown, while NTSC only has 262
  3675. lines of display.  The line synchronization is the same in either PAL or 
  3676. NTSC mode.  It's always 57 clock cycles per rasterline.  The TED divides 
  3677. the supplied crystal frequency by 20 for PAL display and by 16 for NTSC.  
  3678.  
  3679. For the serious video programmer, raster interrupts are implemented as on the
  3680. VIC-II.  However, the 0 line of the register corresponds to the first line
  3681. of the character screen area, not the top of the border.  In addition, the
  3682. current raster line can be read from TED registers.  you can modify the
  3683. counter as well.  Doing so will most likely affect the screen display.  As
  3684. a bonus, the horizontal location of the raster can be read and modified in
  3685. the same way.  Unfortunately, these registers provide the basis for most
  3686. effects, as the TED can't handle sprites.
  3687.  
  3688. @(A): Running The Show
  3689.  
  3690. As earlier mentioned, the TED IC does more than produce graphics.  One of
  3691. its tasks involves generating the clock signal for the 7501/8501 
  3692. microprocessor.  The clock is not constant, as it switches from from
  3693. 885 kHz and twice that speed, 1.773 Mhz.  The speed depends on TED's current
  3694. task.  It generates the slower clock signal when refreshing DRAM or fetching
  3695. data for the video screen.  Otherwise, the high clock signal is generated.
  3696. The user can disable fast clock generation via a register.  The end result
  3697. is a machine that operates at approximately 1 MHz, as the CPU runs in slow
  3698. mode while the screen is displayed, and operates in fast mode when the
  3699. TED starts drawing the top and bottom borders.
  3700.  
  3701. @(A): Sound Advice
  3702.  
  3703. As far as a sound device is concerned, the TED doesn't stack up to the
  3704. SID in the 64.  Just 2 squarewave generators, of which the second can be 
  3705. switched to generate white-noise, are available for sound generation. 
  3706. Volume control is available in 8 levels.  
  3707.  
  3708. To play samples, the TED can switch the sound generators to constant level
  3709. outputs.  D/A is then done by changing the volume register setting.  Each
  3710. generator can generate frequencies from 100Hz to 23kHz.  
  3711.  
  3712. @(A): Other features
  3713.  
  3714. The timers available in the TED appear to be nothing more than 16
  3715. bit decrementing timers.  They are always clocked with the slow clock.  
  3716. The first timer reloads its starting value when it reaches 0, the other 2
  3717. are free-running.   
  3718.  
  3719. Since it already does almost everything else, it's not unusual to notice
  3720. the TED handles the keyboard matrix.  A simple 8-bit imput latch handles
  3721. keyboard interfacing.  
  3722.  
  3723. As noted above, a single bit in the register space will page ROM or
  3724. RAM into the upper 32kB of the address map.  Since the TED knows what is
  3725. paged in at all times, it knows what to output to access the memory
  3726. locations in this area.
  3727.  
  3728. @(A): Conclusion
  3729.  
  3730. Well, that about wraps up the TED IC.  All that is left is a map of the
  3731. registers.  Assume all registers are read/write unless noted otherwise.
  3732. If you have questions, I cna be reached at the Internet address listed above
  3733. or at:
  3734.  
  3735. Harsfalvi Levente
  3736. 7200 Dombovar
  3737. Gorkij 33.
  3738. Hungary
  3739.          
  3740. By the way, catch FLI ED. V1.0; Its info file may contain some more about
  3741. TED's screen-handling. It may be retrieved as 
  3742. ftp://ftp.funet.fi/pub/cbm/plus4/tlc/cns.lzh
  3743.  
  3744. @(A): Register Map
  3745.  
  3746. Register      Description
  3747. --------      -----------
  3748. $ff00- $ff01: Counter #01. It always starts to decrement from the last
  3749.               written value into it.
  3750. $ff02- $ff03: Counter #02. It runs freely from $ffff.
  3751. $ff04- $ff05: Counter #03. Same as above.
  3752. $ff06       : Mostly the same as VIC's $d011.
  3753.               Bit 0,1,2 : Vertical smooth-scrolling
  3754.               Bit 3     : 24/25 rows screen
  3755.               Bit 4     : Blank screen
  3756.               Bit 5     : Bitplane mode
  3757.               Bit 6     : Enhanced color mode
  3758.               Bit 7     : TED's internal test, it should be 0.
  3759. $ff07       : Most similar VIC-reg is $d016.
  3760.               Bit 0,1,2 : Horizontal smooth-scrolling
  3761.               Bit 3     : 40/38 columns screen
  3762.               Bit 4     : Multicolor mode
  3763.               Bit 5     : TED stop. If set, the TED stops it's counters and
  3764.                           screen-generating, only single clock and refresh
  3765.                           cycles remain.
  3766.               Bit 6     : PAL/NTSC. 0:PAL, 1:NTSC
  3767.               Bit 7     : Disable reverse mode. If 0, we got 128 characters
  3768.                           and higmost bit tells if the character should
  3769.                           appear in inverse. If set, no inverse mode but
  3770.                           256 characters.
  3771. $ff08       : Keyboard input latch. Giving a strobe - writing to the register,
  3772.               the latch stores the values of the input-lines. Then, we
  3773.               can read them from this register.
  3774. $ff09       : Interrupt request register. When a counter sends want to send
  3775.               an IRQ, it's bit will appear as a 0; then, if the IRQ was
  3776.               caused then highmost bit is set.
  3777.               Bit 0     : Unused
  3778.               Bit 1     : Raster-counter
  3779.               Bit 2     : Lightpen. Not implemented.
  3780.               Bit 3     : Counter #1
  3781.               Bit 4     : Counter #2
  3782.               Bit 5     : Unused
  3783.               Bit 6     : Counter #3
  3784.               Bit 7     : Interrupt occured. This bit is set when an IRQ
  3785.                           was enabled and therefore, the IRQ was sent to the
  3786.                           processor. Physically, this is the negated level of
  3787.                           the TED's IRQ output. The IRQ should be deleted
  3788.                           with writing the register-value back after
  3789.                           accepting an interrupt.
  3790. $ff0a       : Interrupt mask register. These bits could be used to disable and
  3791.               enable interrupt-sources. When a place is set to 1, that will
  3792.               be able to cause an interrupt to the processor. If not, the sign
  3793.               of the interrupt request will only be appear in the above
  3794.               register.
  3795.               Bit 0     : 9th bit of $ff0b (see there)
  3796.               Bit 1     : Raster-counter
  3797.               Bit 2     : Lightpen. Not implemented.
  3798.               Bit 3     : Counter #1
  3799.               Bit 4     : Counter #2
  3800.               Bit 5     : Unused
  3801.               Bit 6     : Counter #3
  3802.               Bit 7     : Unused
  3803. $ff0b       : Raster interrupt register. Same as $d012 when writing; it stores
  3804.               the position of occuring raster interrupt. Higmost bit is in
  3805.               $ff0a's 0. bit.
  3806. $ff0c,$ff0d : Hardware-cursor position (10 bits). Lower bits: $ff0d, higher
  3807.               2 bits in $ff0c's 0. and 1. places. Beyond 1000 the cursor is
  3808.               not seeable.
  3809. $ff0e       : This reg is the first sound-source's frq-value's lowmost 8 bit.
  3810.               More 2 bits are in $ff10's 0. and 1. places.
  3811. $ff0f       : 2nd. source, lowmost 8 bits. More 2 bits in $ff12, 0. and 1.
  3812.               places.
  3813.               The soundregister-value can be calculated as
  3814.                 reg=1024-(111860.781/frq[Hz]) (NTSC)
  3815.                 reg=1024-(111840.45 /frq[Hz]) (PAL)
  3816. $ff10       : 1st. sound-source, higmost 2 bits. 2-7 bits are unused.
  3817. $ff11       : Sound control register.
  3818.               Bit 0-3   : Volume. Maximum value is 8.
  3819.               Bit 4     : Sound #1 on/off.
  3820.               Bit 5     : Sound #2 squarewave on/off.
  3821.               Bit 6     : Sound #2 noise on/off. If You set both, the square
  3822.                           will sound.
  3823.               Bit 7     : D/A mode. See above for more.
  3824. $ff12       : Bit 0,1   : 2nd sound-source, highmost bits.
  3825.               Bit 2     : Character generator in ROM or RAM. When set, TED
  3826.                           will enable ROM when trying to get data from the
  3827.                           charactergenerator to build screen. Else, it will
  3828.                           give out control-signals to the DRAM's.
  3829.               Bit 3,4,5 : These bits tell, where to find bitplane in the
  3830.                           memory when using bitplane-mode. TED assumes them
  3831.                           as A15,A14 and A13 bits. So, the bitplanes can be
  3832.                           switched as 8K pages, anywhere in the 64K.
  3833.               Bit 6-7   : Unused.
  3834. $ff13         Bit 0     : A sign to having control about memory paging. This
  3835.                           bit always sets to 1 when ROM is active over $8000.
  3836.                           Else, it will be 0. READ ONLY.
  3837.               Bit 1     : Force single clock mode. Then, TED will disable to
  3838.                           generate twiee clock.
  3839.               Bit 2-7   : Charactergenerator. Bit 7 corresponds to A15, 6 to
  3840.                           A14 and so on. This value shows and sets the start
  3841.                           of the charactergenerator. It can be paged as $400
  3842.                           bytes. Use with addition of $ff12-2.bit.
  3843. $ff14         Bit 0-2   : Unused
  3844.               Bit 3-7   : Start of the video-ram. Bit 7 also corresponds to
  3845.                           the A15 line as above. So, video-ram is mappable
  3846.                           as $800 bytes - 2K. The above $ff12-2.bit doesn't
  3847.                           affect this, but the actual RAM/ROM mapping (see at
  3848.                           $ff3e/$ff3f and $ff13/0) does.
  3849. $ff15       : Background. Lower bits contain color-code, higher 3 luminance
  3850.               and higmost is ignored.
  3851. $ff16       : Color-reg 1
  3852. $ff17       : Color-reg 2
  3853. $ff18       : Color reg 3. This and the above are used in ECM and MCM modes.
  3854. $ff19       : Border. All color registers use codes as described in $ff15.
  3855. $ff1a       : Bit 0-1   : Higmost bits of the next $ff1b
  3856.               Bit 2-7   : Unused
  3857. $ff1b       : Actual character-position. Higmost bits in the above register.
  3858.               TED counts the characters that it had fetched and put out to
  3859.               the screen. The number is increasing by 40 after every
  3860.               characterline (8 rasterline).
  3861. $ff1c       : Bit 0     : Higmost bit of $ff1d
  3862.               Bit 1-7   : Unused
  3863. $ff1d       : Actual position of vertical scanning. Higmost
  3864.               bit is in $ff1c. Read/Writeable!
  3865. $ff1e       : Actual position of horizontal scanning. R/W!. Lowmost bit is
  3866.               unused. It contains the TED's internal counter's highmost 8
  3867.               bits. So, it increases 4 with every character. When writing,
  3868.               it seems to put the value to a functionally different register
  3869.               (writing back a reading value in right time affects the screen).
  3870. $ff1f       : Bit 0,1,2 : Actual vertical scanning-line in a character-row.
  3871.                           R/W!.
  3872.               Bit 3-6   : Flashing counter. It's value increases with every
  3873.                           frame, and TED fits it's flashing feature to this
  3874.                           register's reaching to 15.
  3875.               Bit 7     : Unused
  3876. $ff3e       : Switching to ROM. A writing statement to this address will
  3877.               cause to turn on the ROM between $8000-$ffff. It's an other
  3878.               matter, which one; this time, only sure thing that it'll give
  3879.               CS signals instead of RAS', CAS' and MUX.
  3880.               See $ff13/0 and $ff14
  3881. $ff3f       : Switching to RAM. The opposite of the above.
  3882.  
  3883. ============================================================================
  3884.  
  3885. @(#)error: ? DS, DS$: rem The Error Channel
  3886.  
  3887. We are not aware of any errors with issue 11, save the changes to some WWW
  3888. addresses as noted in Hack Surfing (Reference: surf).
  3889.  
  3890. ============================================================================
  3891.  
  3892. @(#)next: The Next Hack
  3893.   
  3894. "... and that's not all you get."  Well, it is for this issue, but here's
  3895. what Commodore Hacking is cooking in its TV informercial cookware for
  3896. issue #13:
  3897.  
  3898. o  CMD has announced that SuperCPU development units should be made
  3899.    available shortly, so C=Hacking will scrutinize it and detail the
  3900.    registers of interest as soon as it shows up.
  3901.  
  3902. o  Exploiting the 65C816S.  We're holding this article over to next issue
  3903.    to allow testing of the examples with the CMD SuperCPU.  This article
  3904.    will detail the new opcodes available to programmers, show how to 
  3905.    detect CPU clock speed on any C64, accelerated or not, and discuss 
  3906.    pitfalls in code migration.
  3907.    
  3908. o  Let's get HTMLized!  It's about time the Commodore 8-bit learned to
  3909.    do HTML.  There's nothing that says this popular WWW markup language 
  3910.    can't do used to create nice disk magazines and newsletters on the 
  3911.    CBM system, so C=Hacking begins a 4 part series on the language and
  3912.    how to render HTML pages on a Commodore machine.
  3913.  
  3914. o  And, of course, C=Hacking's regular goodies.
  3915.  
  3916. So, go ahead, buy that box of disks, and label one now for Commodore
  3917. Hacking Issue #13. 
  3918.  
  3919. ============================================================================
  3920.  
  3921. @(#)editor: Hacking the Code
  3922.  
  3923. For articles in Commodore Hacking that include binary files as part
  3924. of their article, these binaries files are made available in this section
  3925. as encoded text files.  The format used for encoding is called UUCode,
  3926. which is a standard widely used on the Internet to transmit binary files
  3927. using only printable ASCII characters.  To that end, each of these files
  3928. must be decoded with a suitable decoding program before they can executed.
  3929. Typical examples inlucde UUXFER for the 64, uudecode on the ACE OS for the
  3930. 64 and 128, and uudecode on most UNIX OS machines.  Some encoders can decode
  3931. multiple files, while others will require the user to manually split this 
  3932. section into individual pieces prior to decoding.
  3933.  
  3934. WARNING:  The UUCode format trasnlates files from binary to ASCII, not
  3935. PETSCII.  Therefore, either decode this section before downloading this
  3936. section to a PETSCII mode computer system, or download this section without
  3937. translation to PETSCII.  Some decoder programs can handle PETSCII converted
  3938. UUCode files, but the practice is not recommended because conversion is
  3939. typically done in a telecommunications program and cannot be guaranteed to
  3940. be accurate.
  3941.  
  3942. @(A)polycode: Binary for Polygonamy
  3943.  
  3944. begin 600 polygonamy
  3945. M`0@0",0'GC(P-C8@5C4N,````'BB_YJ]-PB=^`#*T/>.$=#N,-"&`:G-H&F%
  3946. M+80NA:Z$KZ`Y3``!`*@%D3_,:;TL"9WH!^C0]^X"`>X%`8C0[J("()T!\"S)
  3947. M!I`2*0&H()H!:0:0"*H@G0&%^1#CA8NE_#CEBX7\A8RE_>D`A?V%C2"&`:;Y
  3948. M\`3&^1#%()T!\`D@F@&B`H:+D!OH()T!\`GH()T!()H!:0%I`X6+Z""=`<@@
  3949. MF@%E_H6,I8UE_X6-.""&`?",I(NE_N6+A?ZP`L;_L8R1_HC0^6"^Z@&I`(6-
  3950. MI/OP#`;Z*B:-QOO*$/*H8(6.L?R%^JD(A?NECJ3\T`+&_<;\P.?0W*3]P`?0
  3951. MUJDWA0'.,-"I&XT1T%BI`(T`""!@IB".IDRNIP,'"PL("@">,C`V,>-_>*E_
  3952. MS+&I-(4RC0R@(KFJ:9G=_XC`_]#USB#JE0CL'0@XC>8!HO.:R&"""B$!F+X+
  3953. M*=@8@$I*4MK(T.KN/PL.0@CN2<B`.0C./`@0V:(.XP<"U)T#<"&=!.`&")T%
  3954. MU*F`G0;4BCCI!ZH0XJ`/J0`*D!>B_XX.U(X/U(T3;GSPCA34HH&.$J!XCXP8
  3955. MU*`"J?^@.-R9`=V(T/?`$+`,N3#@>0#<N4`;W;D`#9D`T,C`+]#E(%`-K3#`
  3956. M>L.M,0.%R*D@H@:-8)F-_M_@#-ZFH`!,C@![69I,!,Y)FHV#"$@@+)!H(,J.
  3957. M)("I"B\UR@(T`U0#=`.4I,5U*PC$'X88AB"Q"L8<A0"E$)$*B!#SQA[*E7?G
  3958. M3`X"?P@(@0$(4[(M_Y5"_P1J8`1X)0`DR@J0&2(#,,84!$BMW:/F8:3.4V)@
  3959. M%*J`F!#P+,KM\`6D!(6$H`O)__#C4`+T\!0&WY`$)M_&ET;_D.$@2(V1W,C0
  3960. M^.;=T.AR[*T2T,F`T/DR#``$W`P`K0C=)N_JZL8!(8"I_XU@`*(*3!$`J7N-
  3961. M$=#F`820A(0``H0"`!#%62@0,$.H`F#___S]""8!`P$`,S@Y,3%JW#`P,'X`
  3962. MQ@8`+P,`BP%`"@!$````O;U*`.J9/_]]F0X"B!#ZC!G0ZH8!:S,`:$`("``P
  3963. M`(!&X>FG>::<X\FZ)TX,YT(&L:@R`%,!T`H<.(8@)&P#&3J,#+!28*)"D!-J
  3964. MO1!,!`(K/*@8>J1P%!=<`"$Q>`EA"Q#Q`HH0`$`,`$P`$(+Q[NY&`$``X>$H
  3965. M`"4`"$%H$1$CBQX>C0"0X"`$!9LWUJ`5R``5</`L"`[^]BD`"!*3_)2%F(B3
  3966. M*P=L/1*,QP`_!@`PGQ&L`'\0$(-Y$/NBF%^E,T0>D30P'N$%,`XAI357'I$V
  3967. M,![=XQ%C0*4WC01,.(PH@HT%<@BQI3F-!MRE.HQB@HT'F@)"W*U`"2T@`]VE
  3968. M,(T-W&`%GC,R-S;/`#@`+C%*+D^B.+W)!94"Y9V1`LH0\^8!J9`L$=`P^\T2
  3969. MT-#VJ0@2X@Q`W7'=H#U(:*4`J0&B"(T.W(X/W*D`HG=,X`$%./'Y,`B!"`4"
  3970. M;P44/A:`#KX$"B=+$`=(ZP"JL9&S(J$X`"`/B@1Q@!F!>@IVHP4&`$"CL[V2
  3971. M-87@&0`!`S"2H`[%H#BHD)FD!2$FC__P!04`"J/F>M`"YGNM!@+).K`*!18C
  3972. M3F/W@Z1DZAJGY*>&KMBL3$BR`#'J`[!'_DKSD?(.\E#R,_-7\<KQ[?8^\2_S
  3973. M9OZE].WUR2#P[T6-!S`XZ=!@@$_'4EA`+/-D57\"!``*@`!O`!&!)H`""0!8
  3974. MIG+V/`,D(PUO8&`(GX,0:*`!%A'$"`L(P=$)()3`!P``)Q@-P'`'A$41A0('
  3975. MA@(&A\#;@>LLIVN`3#)7KR`0#PP9!P\.`0T9`D<3M`OL(%0%$`@%#B`,+B`*
  3976. M%00$`04TG3(8(#(O-B\Y-@+`(3,#%!,@-CHX(#HI`A<T"P'H(`$8O0`,RU<%
  3977. M!@<("0H+#`T.#U"91A.2&Q=)<B0;T9$@J%`06"C@D2&82(SAA8+@(P$+%55E
  3978. MA8JP(U^)C@0L9I2H4!"4;@@I<Y2@4'=R0GM\?7YA"8&"@X2%AH>(B8J+C(V.
  3979. MCY"1DI.4E9:7F)F:FYR=GI^@H:*CI*6FIZBIJJNLK:ZOL+&RL[2UMK>XN;J[
  3980. MO+V^O\#!PL/$Q<;'R,G*R\S-SL_0T=+3U-76U]C9VMO<W=[?X.'BX^3EYN?H
  3981. MZ>KK[.WN[_#Q\O/T]?;W^/GZ^_S]Y>X1!P;Y=Q!TEA44.DL5RIT-%87.DA4%
  3982. M!P7((B`>'!D7%1,0#@P*"`8#`?_]^_GW]?,]XMH1Z.;DXN#>W!36CM&A;$?'
  3983. MQ</!P+Z\NKBW$+D[KZZLJJBGI:.BH)Z=8NZ.E).1D(Z,BXF(AH6#@J`S=Q1W
  3984. M=G1S<7!OA;UC9F5D8F%@7EU<6XB\'4M.34P+CT`ZOO`=1R"/8#P"\@B\+1"W
  3985. M(2!H,+KC"?86B,<1P*,)YA&,QQ'*HP@?``80*((!"`<*B$@+`$@(`4!P`D@%
  3986. M`T"B6T@2'DTHCR/L6C`>2S"/%A8CC<<?'Y/8(R)ACR5D/8(J*[0>04B/(WQ'
  3987. M%]XC3$U.2X];7%U>8&%B9&5F);)[#(&B<W1V=T+W*(*#A8:(B8N,CI"1DY0Z
  3988. MQT>=GJ"BHZ6GJ*JLKJ^0>3ZWN+J\OL#!P\7'0IZ/T:#(Q]S>X.+DYNA0F#Z"
  3989. M\_7W^?O]_P$#!@@*#`X0$Q47&1P>("!>$`$"\)`"`O$``@^;`/[\^OCV]/+P
  3990. M[NSJZ>?EX^'?W=O:V-;4TM#/S<O)R,;$PL&_O;NZN+:UL[&PKJRKJ:>FI*.A
  3991. MGYZ<FYF8EI63DI"/C8R*B8>&A(.!@']]?'IY>'9U=')Q<&YM;&II:&=E9&-B
  3992. M8%]>75M:65A75E134E%03TY-2TI)2$=&141#0D%`/SX]/#LZ.3@W-K[PP30S
  3993. M,C$P+\&Q+2PK*EDH.O0E)!15(HX_!0$5$%1P4(%"!7'A4,%9C$5$!6&B@O`4
  3994. M%A6$(*`G)FH))<`'<"$$BF@`#@L0@4P,`$P(`4P&`N.``PD$3`0%!@8&&%ZG
  3995. MH)R";PH*BJ@I#`P-#0X.#P\0$!$1$A(3$Q04%146%Q<8&!D:&AL<'!T>'A\@
  3996. M("$B(R,D)28F)R@I*2HK+"TN+B\P,3(S-#4U-C<X.3H[/#T^/T!!0D-$149'
  3997. M2$E*2TU.3U!14E-45E=865I;75Y?8&)C9&3_F&EJZ&-P<7)T=79X>7I\?7^`
  3998. M@8.$AH>)BHR-CY"2DY66F)F;G)Z?H:.DIJ>IJZRNL+&SM;:XNKN]O\'"Q,;(
  3999. MR<O-S]#2U-;8VMO=W^'CY>?IZNSN\/+T]OCZ_/ZM@%,F^<V@=$@<\<6:;T09
  4000. M[L2:<$8<\LF@=TXE_=6LA%TU#N:_F7)+)?_9LXUH0AWXU*^+9D(?^]>TD6Y+
  4001. M*`;DPJ!^7#L:^=BWEW96-A;WU[B9>EL]'@#BQ*:);$\R%?C<OZ.';%`U&O_D
  4002. MR:^4>F!&+1/ZX<BPEW]F3C<?!_#9PJN5?FA2/"81_.;1O:B4?VM70S`<"?;C
  4003. MT;ZLFHAV9%-!,!\/_N[>SKZ2KIZ/@'%B5$4W*1L-`/+EV,N_LJ::CH)V:V!5
  4004. M2C\T*B`6#`+Y\.;=U<S$N[.KI)R5CH>`>7-M9F!;55!*14$\-S,O*R<C(!T:
  4005. M%Q01#PT+"0<&!`/_ID?_5298F>`]`0(#!`8'"0L-#Q%2QAH=(",G*R\S-SQ!
  4006. M14I055M@9FUS>8"'CI6<I*NSN\3,U=WF\/D"#!8@*C0_2E5@:W:"CIJFLK_+
  4007. MV.7R``T;*3=%5&)Q@(^>KK[.WN[^#Q\P05-D=HB:K+[1X_8)'#!#5VM_E*B]
  4008. MT>;\$28\4FA^E:O"V?`''S=.9G^7L,CA^A,M1F!ZE*_)Y/\:-5!LAZ._W/@5
  4009. M,D]LB:;$X@`>/5MZF;C7]Q8V5G:7M]CY&CM<?J#"Y`8H2VZ1M-?['T)FBZ_4
  4010. M^!U":(VSV?\E2W*9O^8.-5V$K-7])4YWH,GR'$9PFL3N&41OFL7Q'$ATH,WY
  4011. M)E.`GWZB!!;Z`^Z$,`>XA1D0P@"NJ`*<@)`$$`4/$&X`F5@!2H`/(`.8`!J`
  4012. M`S5$%S8`%Q8!%Q("%PX#%PT$8#H%%PL&%PH'8)@(8`@)%PD*D@M@"`P7"`TR
  4013. M#F`(#X80%P<1(`,2)A-@`A07!A72*P<2D?H)^YB`_`G]F(#^"?^8@``)`9B`
  4014. M`@D#F(`$!Q0%!Q(&`@*#Y)TA-$%*4%9:76!C96=H:FML;6YO;W!Q<7)R<W-T
  4015. M='1U=74;#W8"!'<"!G@""'D""WH"#WL"&'P"$WT(<9L(`%@-`U(&`!0#`!0`
  4016. MB!```01P`D``_Q@\\"A()R8F)B4E)20D)"%9(R(B(B$A(2`@("%9'QX>'AT=
  4017. M'1P<'"%9&QH:&AD9&1@8&"%9%Q86%A45%104%"&Y$Q(2$A$1$1`0$`\/#^%9
  4018. M#@T-#0P,#`L+"R%9"@D)"0@("`<'!R%9!@4%!00$!`,#`R%9`F'^(P```/__
  4019. M_V"%_OW]_?S\_/O[^V2%^OGY^?CX^/?W]V2%]O7U]?3T]//S\^2&\O'Q\?#P
  4020. M\._O[^[N[F>%[>SL[.OKZ^KJZF2%Z>CHZ.?GY^;FYF2%Y>3DY./CX^+BXF2%
  4021. MX>#@X-_?W][>WB@$W=S<W-O;V]K:VMG9V;C%T=[J]P00'2DV0D\@#W6!CIJG
  4022. ML\`=#N;R_PL8)#$^2E=C<'R)C0ZON\C4X>WZ!Q,@+#E%4HT.>(21G:JVP]#<
  4023. MZ?4"#AN-#D%-6F9S?XP=#K*^R]?D\/T*%B,O/$A586Y[AY2@K;G&T]_L^`41
  4024. M'BHW1%!=:7:"CYRHM<'.VN?S``T9)C(_2UAD<7Z*EZ.PO,G6XN_["!0A+3I'
  4025. M4V!L>862GZNXQ-'=ZO8#$!PI-4).6VAT@8V:IK._S-GE\OX+%R0P/4I68V]\
  4026. MB)6BKKO'U.#M^083'RPX15%>:W>$D)VIML+/W.CU`0X:)S1`35EF<G^+F*6Q
  4027. MOLK7X_#\"18B+XUZYJCM`@0`R)!@!0`H!$!,@,`$P`(('`3).]`.Z"@(\!#H
  4028. MQ#+P"\``\`>F'$4Q1R2%!2C0!Z1/Q#+0`>CD'(8<\#S@";`XO(`?Q3+PP.*#
  4029. M$2`P`2$3(C`!(Q,E,`$F$R<P`2@3*C`!*Q,L,`$M$R\P`3`3,3`!,A,T,`$U
  4030. M$S8P`3<3.3`!.A,[,`$\`0@^N0`)D13(QB_0]HT$_ZD`8,E@D`(I7V"@!(0&
  4031. MHC4^V4<@??^.('51++I$:2`-`*(%H"<@A$0@8@!:'<X;!Z\(")B`$`D8F(`@
  4032. M"2B8@#`).)B`0`E(F(!0"5B8@&`):)B`<`EXF("`"8B8@)`)F)B`H`FHF("P
  4033. M";B8@,`)R)B`T`G8F(#@">B8@/`)^"`HL0@(F(`0"1B8@"`)*)B`,$$X(2CU
  4034. M*$)(P`103%C`!&!,:,`$<$QXP`2`3(C`!)!,F,`$H$RHP`2P3+C`!,!,R,`$
  4035. MT$S8P`3@3.C`!/!,^"%`B44(P`003!C`!"!,*,`$,$PXP`1`3$C`!%!,6,`$
  4036. M8$QHP`1P#'@B0JE'$0*()I!@`I@FH&`"J":P8`*X)L!@`L@FT&`"V";@8`+H
  4037. M)O!@`O@B2BP"""808`(8)B!@`B@F,&`"."9`8`)()E!@`E@F8&`":"9P8`)X
  4038. M)H!@`H@FD&`"F":@8`*H)K!@$+@C2CV*$,@P`=`3V#`!X!/H,`'P$_@C4&(1
  4039. M"#`!$!,8,`$@$R@P`3`3.#`!0!-(,`%0$U@P`6`3:#`!<!-X,`&`$X@P`9`3
  4040. MF#`!H!.H,`&P$[@P`<`3R#`!T!/8,`'@$^@P`?`D)20VZE&$@`@)$)B`&`D@
  4041. MF(`H"3"8@#@)0)B`2`E0F(!8"6"8@&@)<)B`>`F`F("("9"8@)@)H)B`J`FP
  4042. MF("X"<"8@,@)T)B`V`G@F(#H"?"8@/@E$HN`"`D0F(`8"2"8@"@),!B$."92
  4043. MCR($2$Q0P`183&#`!&A,<,`$>$R`P`2(3)#`!)A,H,`$J$RPP`2X3,#`!,A,
  4044. MT,`$V$S@P`3H3/#`!/@FE%@$"$P0P`083"#`!"A,,,`$.$Q`P`1(3%#`!%A,
  4045. M8,`$:$QPP"!X)Y1Z%"&(8`*0)IA@`J`FJ&`"L":X8`+`)LA@`M`FV&`"X";H
  4046. M8`+P)O@GH,0B"&`"$"888`(@)BA@`C`F.&`"0"9(8`)0)EA@`F`F:&`"<"9X
  4047. M8`*`)HA@`I`FF&`"H":H8`*P!K@HH=2C"`'($]`P`=@3X#`!Z!/P,`'X*"46
  4048. M`0@3$#`!&!,@,`$H$S`P`3@30#`!2!-0,`%8$V`P`6@3<#`!>!.`,`&($Y`P
  4049. M`9@3H#`!J!.P,`&X$\`P`<@3T#`!V!/@,`'H$_`I4&(IHQY%"`B8@!`)&)B`
  4050. M(`DHF(`P"3B8@$`)2)B`4`E8F(!@"6B8@'`)>)B`@`F(F("0"9B8@*`)J)B`
  4051. ML`FXF(#`"<B8@-`)V)B`X`GHF(#P"?@J*+$(")B`$`D8F(`@"2B8@#!!."LH
  4052. M]2A"2,`$4$Q8P`1@3&C`!'!,>,`$@$R(P`203)C`!*!,J,`$L$RXP`3`3,C`
  4053. M!-!,V,`$X$SHP`3P3/@K0(E%",`$$$P8P`0@3"C`!#!,.,`$0$Q(P`103%C`
  4054. M!&!,:,`$<`QX+$*I1Q$"B":08`*8)J!@`J@FL&`"N";`8`+()M!@`M@FX&`"
  4055. MZ";P8`+X+$HL`@@F$&`"&"8@8`(H)C!@`C@F0&`"2"908`)8)F!@`F@F<&`"
  4056. M>":`8`*()I!@`I@FH&`"J":P8!"X+4H]BA#(,`'0$]@P`>`3Z#`!\!/X+5!B
  4057. M$0@P`1`3&#`!(!,H,`$P$S@P`4`32#`!4!-8,`%@$V@P`7`3>#`!@!.(,`&0
  4058. M$Y@P`:`3J#`!L!.X,`'`$\@P`=`3V#`!X!/H,`'P+B4N-NI1A(`("1"8@!@)
  4059. M()B`*`DPF(`X"4"8@$@)4)B`6`E@F(!H"7"8@'@)@)B`B`F0F("8":"8@*@)
  4060. ML)B`N`G`F(#("="8@-@)X)B`Z`GPF(#X+Q*+@`@)$)B`&`D@F(`H"3`8A#@P
  4061. M4H\B!$A,4,`$6$Q@P`1H3'#`!'A,@,`$B$R0P`283*#`!*A,L,`$N$S`P`3(
  4062. M3-#`!-A,X,`$Z$SPP`3X,)18!`A,$,`$&$P@P`0H3##`!#A,0,`$2$Q0P`18
  4063. M3&#`!&A,<,`@>#&4>A0AB&`"D":88`*@)JA@`K`FN&`"P";(8`+0)MA@`N`F
  4064. MZ&`"\";X,:#$(@A@`A`F&&`"("8H8`(P)CA@`D`F2&`"4"988`)@)FA@`G`F
  4065. M>&`"@":(8`*0)IA@`J`FJ&`"L`:X,J'4HP@!R!/0,`'8$^`P`>@3\#`!^#(E
  4066. M%@$($Q`P`1@3(#`!*!,P,`$X$T`P`4@34#`!6!-@,`%H$W`P`7@3@#`!B!.0
  4067. M,`&8$Z`P`:@3L#`!N!/`,`'($]`P`=@3X#`!Z!/P,U!B,Z,>10@(F(`0"1B8
  4068. M@"`)*)B`,`DXF(!`"4B8@%`)6)B`8`EHF(!P"7B8@(`)B)B`D`F8F("@":B8
  4069. M@+`)N)B`P`G(F(#0"=B8@.`)Z)B`\`GX-"BQ"`B8@!`)&)B`(`DHF(`P03@U
  4070. M*/4H0DC`!%!,6,`$8$QHP`1P3'C`!(!,B,`$D$R8P`2@3*C`!+!,N,`$P$S(
  4071. MP`303-C`!.!,Z,`$\$SX-4")10C`!!!,&,`$($PHP`0P3#C`!$!,2,`$4$Q8
  4072. MP`1@3&C`!'`,>#9"J4<1`H@FD&`"F":@8`*H)K!@`K@FP&`"R";08`+8)N!@
  4073. M`N@F\&`"^#9*+`(()A!@`A@F(&`"*"8P8`(X)D!@`D@F4&`"6"9@8`)H)G!@
  4074. M`G@F@&`"B":08`*8)J!@`J@FL&`0N#=*/8H0R#`!T!/8,`'@$^@P`?`3^#=0
  4075. M8A$(,`$0$Q@P`2`3*#`!,!,X,`%`$T@P`5`36#`!8!-H,`%P$W@P`8`3B#`!
  4076. MD!.8,`&@$Z@P`;`3N#`!P!/(,`'0$]@P`>`3Z#`!\#@E.#;J482`"`D0F(`8
  4077. M"2"8@"@),)B`.`E`F(!("5"8@%@)8)B`:`EPF(!X"8"8@(@)D)B`F`F@F("H
  4078. M";"8@+@)P)B`R`G0F(#8">"8@.@)\)B`^#D2BX`("1"8@!@)()B`*`DP&(0X
  4079. M.KH30$I(P`103%C`!&!,:,`$<$QXP`2`3(C`!)!,F,`$H$RHP`2P3+C`!,!,
  4080. MR,`$T$S8P`3@3.C`!/!,^#I`B44(P`003!C`!"!,*,`$,$PXP`1`3$C`!%!,
  4081. M6,`$8$QHP`1P#'@[0MT)@"6(8`*0)IA@`J`FJ&`"L":X8`+`)LA@`M`FV&`"
  4082. MX";H8`+P)O@[H,0B"&`"$"888`(@)BA@`C`F.&`"0"9(8`)0)EA@`F`F:&`"
  4083. M<"9X8`*`)HA@`I`FF&`"H":H8`*P!K@\H>Z$P!+(,`'0$]@P`>`3Z#`!\!/X
  4084. M/%!B$0@P`1`3&#`!(!,H,`$P$S@P`4`32#`!4!-8,`%@$V@P`7`3>#`!@!.(
  4085. M,`&0$Y@P`:`3J#`!L!.X,`'`$\@P`=`3V#`!X!/H,`'P/24]-GA`\(J`"`D0
  4086. MF(`8"2"8@"@),)B`.`E`F(!("5"8@%@)8)B`:`EPF(!X"8"8@(@)D)B`F`F@
  4087. MF("H";"8@+@)P)B`R`G0F(#8">"8@.@)\)B`^#Z9``P(F(`0"1B8@"`)*)B`
  4088. M,#^9.#\!B.&S(/\>+R#`R@"`8@"`"`!20,!`"<#E"&"K`F$F8F`"8R9E8`)F
  4089. M)F=@`F@F:F`":R9L8`)M)F]@`G`F<6`"<B9T8`)U)G9@`G<F>6`">B9[8`)\
  4090. M)GY@`G\F@&`"@2:#8`*$)H4!"(8@`1`-`$"&`2T`(`$`"`!``0"]`:D/X+&-
  4091. M(=#('B,5A?Q3C_U,38&3#AP1`0Z05T],64=S'DU9#04!$F`<#1\($F&9IT`E
  4092. M-"(4R(W$`$1)3;J)4TE:#B:!A"H*8W-OQE!&CX)LLFH\!T!!!5U32E5$1$!.
  4093. M5U4N1415SR.0`08@<T5%PX19`YYC/6A!0TLRK$Z0($99($16K4%)3%/F!Y4!
  4094. M!R!UFAD).I%`$1&=+Y$[QS01`H!624=!)6*0#9P!!2`^/CX@<"3;Q5\@T$M%
  4095. MD%@H3P$%14<YDB`\/#P-#9IAJ2XN+G-/4E+AE4%"3U5<`N(G0E5'4R$-=&$-
  4096. M&@(!!=Y-DZQ3(%"<`T].04Q)5%D@14Y(04Y#15)3`+'\\"X@TO\F#O8W<#$%
  4097. M!4]W%4$@4T5#4D4(#U1%6%0@34534T%'1303(%E/5R$@Y/_)`/#YI0$I_H4!
  4098. MJ0AT$T<8C1C0K<<.Q`$"@A`%*?P)`[DPK<D)((T1T,#:_(7^80\>:&!,!@"-
  4099. M05DP4*D$A?VI7('7@ZD6LB2,YOWFEBORB8'`2-#WJ1V1_)'^R-#YHL"&6NB&
  4100. M6*(*AFBB#(9JH@Z&;*(0AFZB$H9PD,@=*W*AEB`P`F$2"%*[DNA)M(T$%`(!
  4101. MR$R-`L`-@XTAW(*-(L`-1(U!W+R-0A9`=HT@%HTERP5G\3DV1'@@G_^ER\E`
  4102. M\"_)+LT*0MY)("#)-]`+H@/*_@`6RA#Z,!')+6(W1Z.%3)N"R3+"UP:&$0'F
  4103. M..8YI3H$%P.%.J6QK`+)P#"6$%^QI?@8:0C!Z\"%^*4YE"*L#%UL`#L%`4$H
  4104. MO!0$A3PI"(T_^0!"/<$,`#J%/FTB"CN%0*4\=@!"I?]HA3@#0#C)-`5$ICND
  4105. M//6112EY3$9AG<L*(,E'ID)@QD)(4,*?$-Z`22%X"`%L@E@D]!A(A0GH`L(0
  4106. M%.!`Y@<+?D200$FF0Z1$:HD1$$J0'B/(3:9`OQ,\`%=`6&$"",L2`0Q%"SZD
  4107. M/=)DRCCYL(202Z8_I$)!#:#0ID"D0;VS`8#*&!`!.&HXY?^F/:0^Q'-HRR07
  4108. M`,NU*4RB`-EA!`_)AI`KV>@`)AAY0!:0(,(*A?^$^8I(\`ZT!KD`%L7_D`58
  4109. M%T3RI/F4!VBJZ(@0R\HP)(:MM0?)`%?W`6B)9``!T`8@3(M,=83)`M`#(-"/
  4110. MIJW*$-REO]`_-/$;&*3L`!B%QD`I+EH!X<>B&,%PC%FB(X036Z+(O7`P'-[_
  4111. M6/`7AJ!XBDI*2AAIIX5<BBD'J.(9(7*FIO_*T-R"I22_J<:B>(X8T(T`W:D9
  4112. MA;Q,8X(B5^Z)<(B.(`DL*$5612*>`!<`4S`$1$0IQAT)@0?$0`4P`:$(24Q(
  4113. M&_$05$L@2;<0)%*#1S$F(4$R%1%2,2U,DT]25$%,LA=#$R!.3U0@2E535$E&
  4114. M6=+L2$4@5T%94R!/1B!G3T0@5$\@34%.(B`M+2"0X@!%+D-534U)3D=3YLM6
  4115. M4C`4PA<0"(U0&Q``E!=LA/`%!!KYHY``-$:(XL:LH`.(Z@5``@20,`!,_[F*
  4116. M./VB3`+&_[<<B$`"!)@0%L(`-@@')@J`"87YN4@8,0D8\_D8OHTU?0`7D`+F
  4117. M!`]0S/F90!9`AID`%H@0HV`.KP#(Q<8+,$#8B"ZTK+X`R25&",06>*+_BD@6
  4118. MT3CE0C6W"*;_DD[</%NX8M9(4B-B29%!2K'(H$&E2]AJ1$PL,BA-EAD3PZ5%
  4119. MI#M>&F#!`D:D/#/P0H5'I#V%:[%K2$0L0JAHI)9KP4F`@A04$*@^R0JP7/^J
  4120. MO0`5JJ0>5@HJ%@,/H$*D0'90,$BIH+:"_Y`#YD,5"X9":&4S0TKP!LVP6(B&
  4121. MJ&K)H)`(W#Y"J8D:0Z1!#B0D:29#:2D@9^,!9Q0/::"`1*0_BH5.2F^821QI
  4122. M`44IL6](L6VD_SCQ;87_:/%OI?]<=T$0"UP!#:D`\`D8::C)R)`"J<>%09$:
  4123. M/((893G6'4?NZ8XC6(`8M*,)(D@P0S%H1Q.T@H'&H!U-$$$"2%"0&)JF0"DY
  4124. M>Y'D1,"2$P`)3@0@!2>"0()G7?B3X#&2#)\S8WCG(VQ'BR$S:@QW<P2P6#%X
  4125. MQ(RA=HY@$T-XE1'#5M08!*A@I:Q(..4Z*`P7P7`$3>7!Q9`63;P9,8)-?*&-
  4126. MKB""Q90)$T-:-$1%'C^1.T?&N>!&5<BM+[#)B.&V1@PU2G"-&B7DU8AA+6H,
  4127. MW78$T`K"G'T068QB:(6L:%4``XWA7YI@%7A$D$`Q_$L33(!@%1`LAG]I@@D0
  4128. MK$)3BV`!8OB7)H@@J&7"Q)`R31"(U2E8"HT!)#,2(909"4'*C`2OAREBIR<B
  4129. M$$$H$8@FH!19C$$T:@RG5(0<(;S$B$&5QE!"PX27&#&HTB]8"(DF<C@IAE49
  4130. MI?@3DZ88?&;$L%<U!H<Y@@X0$&K$<$,UACHK0HX0@&C$$$PUAL,IIBG28Z48
  4131. M@++&$$%%8!D5@@.,X;ZJCS+F8KBOO*H\N!CVJPE00+;)<3'L5Z)3OFP,>K8$
  4132. MF@I02N;!Q=!<540Y?4%L:\AQ<G2"V-:0(=B"P(-B33E.04Y/D!(AX,!06$Y1
  4133. MD!-2Q-R6`!(4)%.6$U3D!%4!ISL$R3RIC#(0.AJQT%`;0D,<B4"]J3B:E)@D
  4134. M`@4E%"@CH$`!(V5>7@PGT0F<1"=P$IU`F@S!D@DC<2`4[4@Q),F0-L4+-RA>
  4135. M0#79,C.*%S10O(`RX@4R%*=H,>A$L"8NB9H$+$5-@K`80P"CJ4`E`414400B
  4136. M52@"$5.4TXHQG,0.<!([P$GL`"<A#V+0`0+MC!A.8@<XB1W@)':`DY`',>@`
  4137. M(44'(B@Z0"#1`2!*2/P8_HU3`HMB>(\DX#V2@/=(`DIC"'I8N+="OP0A*G:`
  4138. MJ-@!HF('B`H=(+S'#O`>.\![[`!T,P0:2*;0,`%B1@RN-&.I**)A0E3L`%&Q
  4139. M`T3%#A`5.D`VT0$WB@XU4'2`-0)#()4<IDTA)0&WD03<1A)P&TG`;2`!&P4)
  4140. M'"A(0!I!`AI*_50PQ9-.*/<13Y3["$T*?@0I`-,^)88C*3&8QXB!.222Y0A$
  4141. MRG($!`4YC@2E5(TE.E6-17`/4XT%1U,Q$D`%I5&-)AU2C4;&I5"-!L;D4%C^
  4142. MC`:@V$8'HC5#&)F-_S`#3'6B*D@13(``B6(0D"H(A#B+04"J8`($2!2#@%1N
  4143. M)<?%("!5T`.#RGH,&4R`@0(?.882DJ&,Q(LRY00S.31!RH6&<GJ.3)LU6,XV
  4144. MD7,W)#6^*N(%*Q0O*:!X`2FE2R<H7D`H\0(FBA<F4+B().(%)10O(Z!X`2$T
  4145. MAI"EI;$DT"@MBE4$+L4J@BPR%4<VL8HWH%A%-5"L(C4H53$S%*L(-(I5!#+%
  4146. M*H(R4A5#P(LCY"Z"0W(700.YBR`$10,2%`1)8APA1`EF*""6$R'D!"(I$5]*
  4147. MHXLCY00D.25!2H19DN-B)CDG04XHD"6`I4R8*5A.*I`3*Z1$IR@G?LB$B2SE
  4148. M!"TY+JEBA3NIH84\J7R%/:T"07H^K2+@!C^M0A:%0"!IAJ5!A2^E0H4PI4.%
  4149. M,:4A1AP)(BA(0"`I,B<*$BA0D(`F@@0FE",DH2`!)04)(RA(0"/YD4(@<5*E
  4150. M*HV$A:4KC5ZE*8WI!46JI3"-(?X.,8U!G"^-`<--+[`"7*4MC2)W#BZ-0L:E
  4151. M+(T"QN0L+.NJH`*$^ZD#A:.%_R!VF6"D^UU;!310A?ZH2DI*&*:_T`YI0/0\
  4152. M&C`*0!MAT`QII\B!6H;!O@!;AL*%7(5FA6"I:;);F"D'A?I@".V:LL"Y+9R;
  4153. M0&+2D!9#T!?LG6#:)74!WP@/\F<8D2^\FQ,.HV%6@C]`*Q*"#I@H=A`(Y:FJ
  4154. MF.D`D/KPND.@8-`4C)>*\)2->D":HOJO+O2&1BRU6B"GJBKEJ)`6J(HGN)"0
  4155. M`<@XY;<"YH@P!B"LG$SQI&`8IJ=[YHHE9$6FM98&(X5EJ&JV$03&J&`*M(UF
  4156. M65*J"-W1;I4YH2+T6<)A*NX.1Y*%G\"0.^R<DXB,#UE2J@COD6QPCK2D-,<^
  4157. MHI+*:-$@,$/H#8$9P@(1>+817F!>@F4R+T'8!;;*MD09IB+K<"19^`D,N4.?
  4158. M,]'(C[G%#_V9DKF@!/T,GQ#^`SONYY]-#Y)H@)%HPWD,$L4\BK!`%!0'D`_H
  4159. M.H8`%MF0`QCFJ)$^QXP!/VX-4S*$G\B0.YJAQJ70>Z3\$_<%I*.(X,E9Z84)
  4160. MI83\_?*0<!9Y2+VAXA.G2A^H4"#"#Z2ADZ9*'*96]HBDT@>DQ:0T/ZK$#ZN&
  4161. MJ<:ST'VD_9BJR,2CT`*@ZX/_$`H)_I@)!@#&\.>%LH6SA/V0)0"2<+1`'/D0
  4162. MAK`#3)"=2KT@XH$X0,:%MD^(:JJDLLAUPCCY`,.P!J(`.'Z0%*HXX,2JA5=)
  4163. M_VD`A5FEM'%9./%7ZX*0!^CELL6RL/F%N)A*Y]V&MZ6K?`N&<*2=!B"XQH$2
  4164. M6JNEI^6IA:<1Y@2HBJCKI!K%7_`0A5^!<8U`J#^\7LBQN]`F;R8300&X`!"$
  4165. M3[)?,(="`/$@4JA5(-BE94(]7[`;:0/0%*2GN<D<I+4Y)Q(+$4&P(*1!^K%Q
  4166. M(%6FIJ<@<<S"(%V17::UO0#-,7$18Y'@S+DXY;BP$V6R5-P`&!0#D`Z%N:6U
  4167. MY;>%M:JP)G.V&$Z1\`*4?0#%Q#4#Q67P'"V%PJP(@29,`HHI^!AEP24X"+9E
  4168. MPA.I`:3^D;N8\`G&_@+&^C`&JO9,2*;!<(C&8,9FQERI8,0RH`>$^J5=P0E`
  4169. M7:5>4UZE8\`2@&.E9*9DI<$XZ4"%P:7"Z0&%PDSQHZ1EJ9F16V!L6P"*!V4`
  4170. M;%\``JB]%+='$`@P`1`3&#`!(!,H,`$P$S@P`4`32#`!4!-8,`%@$V@P`7`3
  4171. M>#`!@!,00R$6`9@3H#`!J!.P,`&X$\`P`<@3T#`!V!/@,`'H$_`P`?A@)18!
  4172. M"!,0,`$8$R`P`2@3,#`(.&&E'D4(2)B`4`E8F(!@"6B8@'`)>)B`@`F(F("0
  4173. M"9B8@*`)J)B`L`FXF(#`"<B8@-`)V)B`X`GHF(#P"?AA*+$(")B`$`D8F(`@
  4174. M"2B8@#`).)B`0`E(F(!0"5B8@&`):)B`<$%X8BCU*$*(P`203)C`!*!,J,`$
  4175. ML$RXP`3`3,C`!-!,V,`$X$SHP`3P3/AB0(E%",`$$$P8P`0@3"C`!#!,.,`$
  4176. M0$Q(P`103%C`!&!,:,`$<$QXP`2`3(C`!)!,F,`$H$RHP`2P#+AC0JE'$0+(
  4177. M)M!@`M@FX&`"Z";P8`+X8THL`@@F$&`"&"8@8`(H)C!@`C@F0&`"2"908`)8
  4178. M)F!@`F@F<&`">":`8`*()I!@`I@FH&`"J":P8`*X)L!@`L@FT&`"V";@8`+H
  4179. M)O!DH,1D1CV*$`@P`1`3&#`!(!,H,`$P$S@P`4`32#`!4!-8,`%@$V@P`7`3
  4180. M>#`!@!.(,`&0$Y@P`:`3J#`!L!.X,`'`$\@P`=`3V#`!X!/H,`'P$_AE4&(1
  4181. M"#`!$!,8,`$@$R@P`3"#.&90ZE&$@$@)4)B`6`E@F(!H"7"8@'@)@)B`B`F0
  4182. MF("8":"8@*@)L)B`N`G`F(#("="8@-@)X)B`Z`GPF(#X9A*+@`@)$)B`&`D@
  4183. MF(`H"3"8@#@)0)B`2`E0F(!8"6"8@&@)<!B$>&=2CR($B$R0P`283*#`!*A,
  4184. ML,`$N$S`P`3(3-#`!-A,X,`$Z$SPP`3X9Y18!`A,$,`$&$P@P`0H3##`!#A,
  4185. M0,`$2$Q0P`183&#`!&A,<,`$>$R`P`2(3)#`!)A,H,`$J$RPP""X:)1Z%"'(
  4186. M8`+0)MA@`N`FZ&`"\";X:*#$(@A@`A`F&&`"("8H8`(P)CA@`D`F2&`"4"98
  4187. M8`)@)FA@`G`F>&`"@":(8`*0)IA@`J`FJ&`"L":X8`+`)LA@`M`FV&`"X";H
  4188. M8`+P:4II;-2C"`$($Q`P`1@3(#`!*!,P,`$X$T`P`4@34#`!6!-@,`%H$W`P
  4189. M`7@3@#`!B!.0,`&8$Z`P`:@3L#`!N!/`,`'($]`P`=@3X#`!Z!/P,`'X:B46
  4190. M`0@3$#`!&!,@,`$H$S`P"#AKI1Y%"$B8@%`)6)B`8`EHF(!P"7B8@(`)B)B`
  4191. MD`F8F("@":B8@+`)N)B`P`G(F(#0"=B8@.`)Z)B`\`GX:RBQ"`B8@!`)&)B`
  4192. M(`DHF(`P"3B8@$`)2)B`4`E8F(!@"6B8@'!!>&PH]2A"B,`$D$R8P`2@3*C`
  4193. M!+!,N,`$P$S(P`303-C`!.!,Z,`$\$SX;$")10C`!!!,&,`$($PHP`0P3#C`
  4194. M!$!,2,`$4$Q8P`1@3&C`!'!,>,`$@$R(P`203)C`!*!,J,`$L`RX;4*I1Q$"
  4195. MR";08`+8)N!@`N@F\&`"^&U*+`(()A!@`A@F(&`"*"8P8`(X)D!@`D@F4&`"
  4196. M6"9@8`)H)G!@`G@F@&`"B":08`*8)J!@`J@FL&`"N";`8`+()M!@`M@FX&`"
  4197. MZ";P;J#$;D8]BA`(,`$0$Q@P`2`3*#`!,!,X,`%`$T@P`5`36#`!8!-H,`%P
  4198. M$W@P`8`3B#`!D!.8,`&@$Z@P`;`3N#`!P!/(,`'0$]@P`>`3Z#`!\!/X;U!B
  4199. M$0@P`1`3&#`!(!,H,`$P@SAP4.I1A(!("5"8@%@)8)B`:`EPF(!X"8"8@(@)
  4200. MD)B`F`F@F("H";"8@+@)P)B`R`G0F(#8">"8@.@)\)B`^'`2BX`("1"8@!@)
  4201. M()B`*`DPF(`X"4"8@$@)4)B`6`E@F(!H"7`8A'AQ4H\B!(A,D,`$F$R@P`2H
  4202. M3+#`!+A,P,`$R$S0P`383.#`!.A,\,`$^'&46`0(3!#`!!A,(,`$*$PPP`0X
  4203. M3$#`!$A,4,`$6$Q@P`1H3'#`!'A,@,`$B$R0P`283*#`!*A,L,`@N'*4>A0A
  4204. MR&`"T";88`+@)NA@`O`F^'*@Q"((8`(0)AA@`B`F*&`","8X8`)`)DA@`E`F
  4205. M6&`"8"9H8`)P)GA@`H`FB&`"D":88`*@)JA@`K`FN&`"P";(8`+0)MA@`N`F
  4206. MZ&`"\'-*<VS4HP@!"!,0,`$8$R`P`2@3,#`!.!-`,`%($U`P`5@38#`!:!-P
  4207. M,`%X$X`P`8@3D#`!F!.@,`&H$[`P`;@3P#`!R!/0,`'8$^`P`>@3\#`!^'0E
  4208. M%@$($Q`P`1@3(#`!*!,P,`@X=:4>10A(F(!0"5B8@&`):)B`<`EXF("`"8B8
  4209. M@)`)F)B`H`FHF("P";B8@,`)R)B`T`G8F(#@">B8@/`)^'4HL0@(F(`0"1B8
  4210. M@"`)*)B`,`DXF(!`"4B8@%`)6)B`8`EHF(!P07AV*/4H0HC`!)!,F,`$H$RH
  4211. MP`2P3+C`!,!,R,`$T$S8P`3@3.C`!/!,^'9`B44(P`003!C`!"!,*,`$,$PX
  4212. MP`1`3$C`!%!,6,`$8$QHP`1P3'C`!(!,B,`$D$R8P`2@3*C`!+`,N'="J4<1
  4213. M`L@FT&`"V";@8`+H)O!@`OAW2BP"""808`(8)B!@`B@F,&`"."9`8`)()E!@
  4214. M`E@F8&`":"9P8`)X)H!@`H@FD&`"F":@8`*H)K!@`K@FP&`"R";08`+8)N!@
  4215. M`N@F\'B@Q'A&/8H0"#`!$!,8,`$@$R@P`3`3.#`!0!-(,`%0$U@P`6`3:#`!
  4216. M<!-X,`&`$X@P`9`3F#`!H!.H,`&P$[@P`<`3R#`!T!/8,`'@$^@P`?`3^'E0
  4217. M8A$(,`$0$Q@P`2`3*#`!,(,X>E!W0D`)2)B`4`E8F(!@"6B8@'`)>)B`@`F(
  4218. MF("0"9B8@*`)J)B`L`FXF(#`"<B8@-`)V)B`X`GHF(#P"?AZ*+$(")B`$`D8
  4219. MF(`@"2B8@#`).)B`0`E(F(!0"5B8@&`):)B`<$%X>Z@[@*$$B$R0P`283*#`
  4220. M!*A,L,`$N$S`P`3(3-#`!-A,X,`$Z$SPP`3X>Y18!`A,$,`$&$P@P`0H3##`
  4221. M!#A,0,`$2$Q0P`183&#`!&A,<,`$>$R`P`2(3)#`!)A,H,`$J$RPP""X?-2=
  4222. MP%`"R";08`+8)N!@`N@F\&`"^'Q*+`(()A!@`A@F(&`"*"8P8`(X)D!@`D@F
  4223. M4&`"6"9@8`)H)G!@`G@F@&`"B":08`*8)J!@`J@FL&`"N";`8`+()M!@`M@F
  4224. MX&`"Z";P?:#$?28/`?&*@`@)$)B`&`D@F(`H"3"8@#@)0)B`2`E0F(!8"6"8
  4225. M@&@)<)B`>`F`F("("9"8@)@)H)B`J`FPF("X"<"8@,@)T)B`V`G@F(#H"?"8
  4226. M@/A^F0`,")B`$`D8F(`@"2B8@#!_F3A_`8AAGX`!@@2&"8P0E!F>)*HQN$#(
  4227. M4=ID[GD$D!RI-L12X7``D"&R1-9I_)`DN4[D>A&H0-AQ"J0^V700K$GFA"+!
  4228. M8`"@0>*$)LEL$+19_J1*\9A`Z)$ZY(XYY)`\Z99$\J%0`+!A$L1V*=R01/FN
  4229. M9!K1B$#XL6HDWIE4$,R)1@3"@4``P(%"!,:)3!#4F5XDZK%X0`C1FF0N^<20
  4230. M7"GVQ))A,`#0H7)$%NF\D&0Y#N2ZD6A`&/'*I'Y9-!#LR::$8D$@`.#!HH1F
  4231. M22P0]-F^I(IQ6$`H$?KDSKFDD'QI5D0R(1``\.'2Q+:IG)"$>6YD6E%(0#@Q
  4232. M*B0>&100#`D&!`+W_P`!`@0&"0P0%!D>)"HQ.$!(45ID;GF$D)RIML32X?``
  4233. M$"$R1%9I?)"DN<[D^A$H0%AQBJ2^V?00+$EFA*+!X``@06*$ILGL$#19?J3*
  4234. M\1A`:)&ZY`XY9)"\Z19$<J'0`#!ADL3V*5R0Q/DN9)K1"$!XL>HD7IG4$$R)
  4235. MQ@1"@<``0('"!$:)S!!4F=XD:K'X0(C1&F2N^420W"EVQ!)AL`!0H?)$END\
  4236. MD.0YCN0ZD>A`F/%*I/Y9M!!LR2:$XD&@`&#!(H3F2:P0=-D^I`IQV$"H$7KD
  4237. M3KDDD/QIUD2R(9``<.%2Q#:I')`$>>YDVE'(0+@QJB2>&900C`F&!((!@$?^
  4238. M`1/];R(W15!:86AN<WA\@(2(BXZN]@]9G9^AHZ6GJ:JLKJ^QLK2UMKC*>B*\
  4239. MOK_`0HW$Q<;'R,G*2)@DS<XBE`C2BDL$,!$$F@AN(MS<XHG?W^#@4-.",!1!
  4240. MIN;GY^CHZ>GJZNOK[.SM[>WN[N_O\/#P\?'R\O+S\_3T]/6%X[)Y?]G9VMK:
  4241. MV]O;8H7<W=W=WM[>W]_?9(*PJB`$X@SCY.3D00;E3.;`".>,"!$,D"";0<#-
  4242. M(``080`("`$`#P`"(7IF.CHC`3H5`CH.`SH,!#H)!3K0FC("!SH&"#()8`@*
  4243. MY@LZ!0P-#0TZ!`X/#P\0$!`1$1$2$A(3$Q04%!45%A87%Q@8&1D:(,CW*0CX
  4244. M5"`A(2(C(R0E)B8G*"DJ*RLL+2XO,#$R,S0U-C<X.3L\/3Y`U/%F"9AE3"C*
  4245. M45)45EA96UU?86-E9VEK;6]R='9Y>WZ`@X6(BXTOKB29G)^95P,D`083"3`!
  4246. M#!,/,`$2$Q4P`1@3&S`!'A,A,`$D$R<P`2H3+3`!,!,S,`$V$SDP`3P3/S`!
  4247. M0A-%,`%($TLP`4X343`!5!-7,`%:$UT!"&"0'5P`@@)J_`!.`$Y4=#450\6L
  4248. M='AA8"<^/CX@;75L=,5V<X-'3@5%A$!XH$A)1TB@0EE480Q&,RY9"")T99'H
  4249. M0D4(/41T-UIP;(/8<&]S>7)P3U-)(Q&`H$]2MJ`_E!]LY"(V:88D2)`P5$A%
  4250. M3I$G8605(S$V.),Y041$+*!!3D2@24:@<W1I;&R@3D5'051)5D4N+BXOCF-M
  4251. M<'`1,@,1!V)C8R`Z;VL-(&QD82`C,#`@.W-%5*!43Z!:10$M'A!5"/\`[N[N
  4252. M`+N[QP!`4%6[@0"`JA&J1"A@510`(`!5JA0`[MV[=Q`!@'>[W>X(`+M5[C2%
  4253. M?D$!`O_;3IF]P]3!K1@$YY#%(``,`(D@``S_D`$@&.<@!`!&&-O,``!^O5,"
  4254. M!O]^`0EKH@0$0``P]^OW[]?O"#8`,"("6/O5J]\`5RW?J]7]/`@`_]^OW_OU
  4255. M^_\!I'$ORZ&/U@%B'P+L!I[`J;Z]O+NZN+>UL[&OK:NIIJ2AGIN8EI.0C(F&
  4256. M@X!]>G=T<&UJ:&5B7UQ:5U5344]-2TE(1D5$0T(;\X$!!4!!04)#1$5&2$E+
  4257. M34]14U576EQ?$/^H:FUP='=Z?8"#AHF,D).6F)N>H:2FJ:NMK[&SM;>XNKMH
  4258. M?*B"H0H!`00:D.:!0,8@("`!"(!N``(#!08("0L,#@\0$A,4%1<8&1KNB!P=
  4259. M2H@!0"`?'Q\>'AT<&QL:&1@7%103$A`/#@P+"0@&!0,"`/[]^_KX]_7T\O'P
  4260. M[NWLZ^GHY^;GRB/DXRHA!@$'X.'AX>+BX^3EY>;GZ.GK[.WN\/'R]/7W^/K[
  4261. M_?Z0<0!\`P">`0#'`(`%`/]_/Q\/!P,!)#$`O@$`SP"`8P#``@"`P.#P^/P2
  4262. MV#8,F'^]U(`Z`X(&`""#0/0`O?7V]O;W]_?X^/GY^?KZ^OO[^_S\_/W]_?[^
  4263. M_MC%1;2P`04-(W``"$30`"((YB$`B#``!(2`__#_`00`_P`"`!0!%2,N-S]&
  4264. M3%%66EYB96AL;G%T=GA[?7^!@X6&B(J+C8Z0D9.4E9>8F9J;G)Z?H*&BHZ2E
  4265. MIJ>GJ*FJJZRMK:ZOL+"QLK.SM+6UMK>WN+FYNKN[O+R]OKZ_O\#`P<'"P\/$
  4266. MQ,7%QL;'Q\?(R,G)RLK+R\S,S,W-SL[/S\_0T-'1T=+2T]/3U-34U=75UM;7
  4267. MU]?8V-C9V9#F`;``@(03))0PO3'JI$?^2O.1\@[R4/(S\U?QRO'M]C[Q+_-F
  4268. M_J7T[?4!L$6,`P"]`0$`O1H:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:
  4269. ,&AH:&AH:&AH:&AH:
  4270. `
  4271. end
  4272.  
  4273. =========================================================================
  4274. @(#): bottom
  4275.  
  4276. --
  4277. Jim Brain, Embedded System Designer, Brain Innovations, Inc. (BII) (online sig)
  4278. brain@mail.msen.com "Above views DO reflect my employer, since I'm my employer"
  4279. Dabbling in WWW, Embedded Systems, VR, Old CBM computers, and Good Times!  -Me-
  4280. <a href=http://www.msen.com/~brain/>Jim Brain: BII, VR, and CBM info</a>    
  4281.